summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/andybalholm/cascadia
diff options
context:
space:
mode:
author6543 <6543@obermui.de>2021-06-10 16:44:25 +0200
committerGitHub <noreply@github.com>2021-06-10 16:44:25 +0200
commit86e2789960439ca786c6e7a74f85f076c223d148 (patch)
treec63064d4258bcf2bb7a2e5e60acc0a5d5c8216da /vendor/github.com/andybalholm/cascadia
parentf088dc4ea14ae6304c2e06fca06ffa2f7bc273f3 (diff)
downloadgitea-86e2789960439ca786c6e7a74f85f076c223d148.tar.gz
gitea-86e2789960439ca786c6e7a74f85f076c223d148.zip
Vendor Update (#16121)
* update github.com/PuerkitoBio/goquery * update github.com/alecthomas/chroma * update github.com/blevesearch/bleve/v2 * update github.com/caddyserver/certmagic * update github.com/go-enry/go-enry/v2 * update github.com/go-git/go-billy/v5 * update github.com/go-git/go-git/v5 * update github.com/go-redis/redis/v8 * update github.com/go-testfixtures/testfixtures/v3 * update github.com/jaytaylor/html2text * update github.com/json-iterator/go * update github.com/klauspost/compress * update github.com/markbates/goth * update github.com/mattn/go-isatty * update github.com/mholt/archiver/v3 * update github.com/microcosm-cc/bluemonday * update github.com/minio/minio-go/v7 * update github.com/prometheus/client_golang * update github.com/unrolled/render * update github.com/xanzy/go-gitlab * update github.com/yuin/goldmark * update github.com/yuin/goldmark-highlighting Co-authored-by: techknowlogick <techknowlogick@gitea.io>
Diffstat (limited to 'vendor/github.com/andybalholm/cascadia')
-rw-r--r--vendor/github.com/andybalholm/cascadia/go.mod6
-rw-r--r--vendor/github.com/andybalholm/cascadia/parser.go93
-rw-r--r--vendor/github.com/andybalholm/cascadia/selector.go113
-rw-r--r--vendor/github.com/andybalholm/cascadia/serialize.go120
4 files changed, 298 insertions, 34 deletions
diff --git a/vendor/github.com/andybalholm/cascadia/go.mod b/vendor/github.com/andybalholm/cascadia/go.mod
index e6febbbfed..51a330b500 100644
--- a/vendor/github.com/andybalholm/cascadia/go.mod
+++ b/vendor/github.com/andybalholm/cascadia/go.mod
@@ -1,3 +1,5 @@
-module "github.com/andybalholm/cascadia"
+module github.com/andybalholm/cascadia
-require "golang.org/x/net" v0.0.0-20180218175443-cbe0f9307d01
+require golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01
+
+go 1.13
diff --git a/vendor/github.com/andybalholm/cascadia/parser.go b/vendor/github.com/andybalholm/cascadia/parser.go
index 4f8810e3ef..c40a39fed1 100644
--- a/vendor/github.com/andybalholm/cascadia/parser.go
+++ b/vendor/github.com/andybalholm/cascadia/parser.go
@@ -13,6 +13,10 @@ import (
type parser struct {
s string // the source text
i int // the current position
+
+ // if `false`, parsing a pseudo-element
+ // returns an error.
+ acceptPseudoElements bool
}
// parseEscape parses a backslash escape.
@@ -29,7 +33,7 @@ func (p *parser) parseEscape() (result string, err error) {
case hexDigit(c):
// unicode escape (hex)
var i int
- for i = start; i < p.i+6 && i < len(p.s) && hexDigit(p.s[i]); i++ {
+ for i = start; i < start+6 && i < len(p.s) && hexDigit(p.s[i]); i++ {
// empty
}
v, _ := strconv.ParseUint(p.s[start:i], 16, 21)
@@ -422,17 +426,25 @@ var errExpectedParenthesis = errors.New("expected '(' but didn't find it")
var errExpectedClosingParenthesis = errors.New("expected ')' but didn't find it")
var errUnmatchedParenthesis = errors.New("unmatched '('")
-// parsePseudoclassSelector parses a pseudoclass selector like :not(p)
-func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
+// parsePseudoclassSelector parses a pseudoclass selector like :not(p) or a pseudo-element
+// For backwards compatibility, both ':' and '::' prefix are allowed for pseudo-elements.
+// https://drafts.csswg.org/selectors-3/#pseudo-elements
+// Returning a nil `Sel` (and a nil `error`) means we found a pseudo-element.
+func (p *parser) parsePseudoclassSelector() (out Sel, pseudoElement string, err error) {
if p.i >= len(p.s) {
- return nil, fmt.Errorf("expected pseudoclass selector (:pseudoclass), found EOF instead")
+ return nil, "", fmt.Errorf("expected pseudoclass selector (:pseudoclass), found EOF instead")
}
if p.s[p.i] != ':' {
- return nil, fmt.Errorf("expected attribute selector (:pseudoclass), found '%c' instead", p.s[p.i])
+ return nil, "", fmt.Errorf("expected attribute selector (:pseudoclass), found '%c' instead", p.s[p.i])
}
p.i++
+ var mustBePseudoElement bool
+ if p.i >= len(p.s) {
+ return nil, "", fmt.Errorf("got empty pseudoclass (or pseudoelement)")
+ }
if p.s[p.i] == ':' { // we found a pseudo-element
+ mustBePseudoElement = true
p.i++
}
@@ -441,27 +453,33 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
return
}
name = toLowerASCII(name)
+ if mustBePseudoElement && (name != "after" && name != "backdrop" && name != "before" &&
+ name != "cue" && name != "first-letter" && name != "first-line" && name != "grammar-error" &&
+ name != "marker" && name != "placeholder" && name != "selection" && name != "spelling-error") {
+ return out, "", fmt.Errorf("unknown pseudoelement :%s", name)
+ }
+
switch name {
case "not", "has", "haschild":
if !p.consumeParenthesis() {
- return out, errExpectedParenthesis
+ return out, "", errExpectedParenthesis
}
sel, parseErr := p.parseSelectorGroup()
if parseErr != nil {
- return out, parseErr
+ return out, "", parseErr
}
if !p.consumeClosingParenthesis() {
- return out, errExpectedClosingParenthesis
+ return out, "", errExpectedClosingParenthesis
}
out = relativePseudoClassSelector{name: name, match: sel}
case "contains", "containsown":
if !p.consumeParenthesis() {
- return out, errExpectedParenthesis
+ return out, "", errExpectedParenthesis
}
if p.i == len(p.s) {
- return out, errUnmatchedParenthesis
+ return out, "", errUnmatchedParenthesis
}
var val string
switch p.s[p.i] {
@@ -471,46 +489,46 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
val, err = p.parseIdentifier()
}
if err != nil {
- return out, err
+ return out, "", err
}
val = strings.ToLower(val)
p.skipWhitespace()
if p.i >= len(p.s) {
- return out, errors.New("unexpected EOF in pseudo selector")
+ return out, "", errors.New("unexpected EOF in pseudo selector")
}
if !p.consumeClosingParenthesis() {
- return out, errExpectedClosingParenthesis
+ return out, "", errExpectedClosingParenthesis
}
out = containsPseudoClassSelector{own: name == "containsown", value: val}
case "matches", "matchesown":
if !p.consumeParenthesis() {
- return out, errExpectedParenthesis
+ return out, "", errExpectedParenthesis
}
rx, err := p.parseRegex()
if err != nil {
- return out, err
+ return out, "", err
}
if p.i >= len(p.s) {
- return out, errors.New("unexpected EOF in pseudo selector")
+ return out, "", errors.New("unexpected EOF in pseudo selector")
}
if !p.consumeClosingParenthesis() {
- return out, errExpectedClosingParenthesis
+ return out, "", errExpectedClosingParenthesis
}
out = regexpPseudoClassSelector{own: name == "matchesown", regexp: rx}
case "nth-child", "nth-last-child", "nth-of-type", "nth-last-of-type":
if !p.consumeParenthesis() {
- return out, errExpectedParenthesis
+ return out, "", errExpectedParenthesis
}
a, b, err := p.parseNth()
if err != nil {
- return out, err
+ return out, "", err
}
if !p.consumeClosingParenthesis() {
- return out, errExpectedClosingParenthesis
+ return out, "", errExpectedClosingParenthesis
}
last := name == "nth-last-child" || name == "nth-last-of-type"
ofType := name == "nth-of-type" || name == "nth-last-of-type"
@@ -535,9 +553,9 @@ func (p *parser) parsePseudoclassSelector() (out Sel, err error) {
case "root":
out = rootPseudoClassSelector{}
case "after", "backdrop", "before", "cue", "first-letter", "first-line", "grammar-error", "marker", "placeholder", "selection", "spelling-error":
- return out, errors.New("pseudo-elements are not yet supported")
+ return nil, name, nil
default:
- return out, fmt.Errorf("unknown pseudoclass or pseudoelement :%s", name)
+ return out, "", fmt.Errorf("unknown pseudoclass or pseudoelement :%s", name)
}
return
}
@@ -706,11 +724,13 @@ func (p *parser) parseSimpleSelectorSequence() (Sel, error) {
selectors = append(selectors, r)
}
+ var pseudoElement string
loop:
for p.i < len(p.s) {
var (
- ns Sel
- err error
+ ns Sel
+ newPseudoElement string
+ err error
)
switch p.s[p.i] {
case '#':
@@ -720,20 +740,37 @@ loop:
case '[':
ns, err = p.parseAttributeSelector()
case ':':
- ns, err = p.parsePseudoclassSelector()
+ ns, newPseudoElement, err = p.parsePseudoclassSelector()
default:
break loop
}
if err != nil {
return nil, err
}
+ // From https://drafts.csswg.org/selectors-3/#pseudo-elements :
+ // "Only one pseudo-element may appear per selector, and if present
+ // it must appear after the sequence of simple selectors that
+ // represents the subjects of the selector.""
+ if ns == nil { // we found a pseudo-element
+ if pseudoElement != "" {
+ return nil, fmt.Errorf("only one pseudo-element is accepted per selector, got %s and %s", pseudoElement, newPseudoElement)
+ }
+ if !p.acceptPseudoElements {
+ return nil, fmt.Errorf("pseudo-element %s found, but pseudo-elements support is disabled", newPseudoElement)
+ }
+ pseudoElement = newPseudoElement
+ } else {
+ if pseudoElement != "" {
+ return nil, fmt.Errorf("pseudo-element %s must be at the end of selector", pseudoElement)
+ }
+ selectors = append(selectors, ns)
+ }
- selectors = append(selectors, ns)
}
- if len(selectors) == 1 { // no need wrap the selectors in compoundSelector
+ if len(selectors) == 1 && pseudoElement == "" { // no need wrap the selectors in compoundSelector
return selectors[0], nil
}
- return compoundSelector{selectors: selectors}, nil
+ return compoundSelector{selectors: selectors, pseudoElement: pseudoElement}, nil
}
// parseSelector parses a selector that may include combinators.
diff --git a/vendor/github.com/andybalholm/cascadia/selector.go b/vendor/github.com/andybalholm/cascadia/selector.go
index 18ce116440..e2a6dc4be1 100644
--- a/vendor/github.com/andybalholm/cascadia/selector.go
+++ b/vendor/github.com/andybalholm/cascadia/selector.go
@@ -16,14 +16,19 @@ type Matcher interface {
}
// Sel is the interface for all the functionality provided by selectors.
-// It is currently the same as Matcher, but other methods may be added in the
-// future.
type Sel interface {
Matcher
Specificity() Specificity
+
+ // Returns a CSS input compiling to this selector.
+ String() string
+
+ // Returns a pseudo-element, or an empty string.
+ PseudoElement() string
}
-// Parse parses a selector.
+// Parse parses a selector. Use `ParseWithPseudoElement`
+// if you need support for pseudo-elements.
func Parse(sel string) (Sel, error) {
p := &parser{s: sel}
compiled, err := p.parseSelector()
@@ -38,7 +43,25 @@ func Parse(sel string) (Sel, error) {
return compiled, nil
}
+// ParseWithPseudoElement parses a single selector,
+// with support for pseudo-element.
+func ParseWithPseudoElement(sel string) (Sel, error) {
+ p := &parser{s: sel, acceptPseudoElements: true}
+ compiled, err := p.parseSelector()
+ if err != nil {
+ return nil, err
+ }
+
+ if p.i < len(sel) {
+ return nil, fmt.Errorf("parsing %q: %d bytes left over", sel, len(sel)-p.i)
+ }
+
+ return compiled, nil
+}
+
// ParseGroup parses a selector, or a group of selectors separated by commas.
+// Use `ParseGroupWithPseudoElements`
+// if you need support for pseudo-elements.
func ParseGroup(sel string) (SelectorGroup, error) {
p := &parser{s: sel}
compiled, err := p.parseSelectorGroup()
@@ -53,6 +76,22 @@ func ParseGroup(sel string) (SelectorGroup, error) {
return compiled, nil
}
+// ParseGroupWithPseudoElements parses a selector, or a group of selectors separated by commas.
+// It supports pseudo-elements.
+func ParseGroupWithPseudoElements(sel string) (SelectorGroup, error) {
+ p := &parser{s: sel, acceptPseudoElements: true}
+ compiled, err := p.parseSelectorGroup()
+ if err != nil {
+ return nil, err
+ }
+
+ if p.i < len(sel) {
+ return nil, fmt.Errorf("parsing %q: %d bytes left over", sel, len(sel)-p.i)
+ }
+
+ return compiled, nil
+}
+
// A Selector is a function which tells whether a node matches or not.
//
// This type is maintained for compatibility; I recommend using the newer and
@@ -182,6 +221,10 @@ func (c tagSelector) Specificity() Specificity {
return Specificity{0, 0, 1}
}
+func (c tagSelector) PseudoElement() string {
+ return ""
+}
+
type classSelector struct {
class string
}
@@ -197,6 +240,10 @@ func (c classSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c classSelector) PseudoElement() string {
+ return ""
+}
+
type idSelector struct {
id string
}
@@ -212,6 +259,10 @@ func (c idSelector) Specificity() Specificity {
return Specificity{1, 0, 0}
}
+func (c idSelector) PseudoElement() string {
+ return ""
+}
+
type attrSelector struct {
key, val, operation string
regexp *regexp.Regexp
@@ -352,6 +403,10 @@ func (c attrSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c attrSelector) PseudoElement() string {
+ return ""
+}
+
// ---------------- Pseudo class selectors ----------------
// we use severals concrete types of pseudo-class selectors
@@ -415,6 +470,10 @@ func (s relativePseudoClassSelector) Specificity() Specificity {
return max
}
+func (c relativePseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type containsPseudoClassSelector struct {
own bool
value string
@@ -436,6 +495,10 @@ func (s containsPseudoClassSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c containsPseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type regexpPseudoClassSelector struct {
own bool
regexp *regexp.Regexp
@@ -488,6 +551,10 @@ func (s regexpPseudoClassSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c regexpPseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type nthPseudoClassSelector struct {
a, b int
last, ofType bool
@@ -623,6 +690,10 @@ func (s nthPseudoClassSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c nthPseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type onlyChildPseudoClassSelector struct {
ofType bool
}
@@ -661,6 +732,10 @@ func (s onlyChildPseudoClassSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c onlyChildPseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type inputPseudoClassSelector struct{}
// Matches input, select, textarea and button elements.
@@ -672,6 +747,10 @@ func (s inputPseudoClassSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c inputPseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type emptyElementPseudoClassSelector struct{}
// Matches empty elements.
@@ -694,6 +773,10 @@ func (s emptyElementPseudoClassSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c emptyElementPseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type rootPseudoClassSelector struct{}
// Match implements :root
@@ -711,8 +794,13 @@ func (s rootPseudoClassSelector) Specificity() Specificity {
return Specificity{0, 1, 0}
}
+func (c rootPseudoClassSelector) PseudoElement() string {
+ return ""
+}
+
type compoundSelector struct {
- selectors []Sel
+ selectors []Sel
+ pseudoElement string
}
// Matches elements if each sub-selectors matches.
@@ -734,9 +822,17 @@ func (s compoundSelector) Specificity() Specificity {
for _, sel := range s.selectors {
out = out.Add(sel.Specificity())
}
+ if s.pseudoElement != "" {
+ // https://drafts.csswg.org/selectors-3/#specificity
+ out = out.Add(Specificity{0, 0, 1})
+ }
return out
}
+func (c compoundSelector) PseudoElement() string {
+ return c.pseudoElement
+}
+
type combinedSelector struct {
first Sel
combinator byte
@@ -818,6 +914,15 @@ func (s combinedSelector) Specificity() Specificity {
return spec
}
+// on combinedSelector, a pseudo-element only makes sens on the last
+// selector, although others increase specificity.
+func (c combinedSelector) PseudoElement() string {
+ if c.second == nil {
+ return ""
+ }
+ return c.second.PseudoElement()
+}
+
// A SelectorGroup is a list of selectors, which matches if any of the
// individual selectors matches.
type SelectorGroup []Sel
diff --git a/vendor/github.com/andybalholm/cascadia/serialize.go b/vendor/github.com/andybalholm/cascadia/serialize.go
new file mode 100644
index 0000000000..f15b079527
--- /dev/null
+++ b/vendor/github.com/andybalholm/cascadia/serialize.go
@@ -0,0 +1,120 @@
+package cascadia
+
+import (
+ "fmt"
+ "strings"
+)
+
+// implements the reverse operation Sel -> string
+
+func (c tagSelector) String() string {
+ return c.tag
+}
+
+func (c idSelector) String() string {
+ return "#" + c.id
+}
+
+func (c classSelector) String() string {
+ return "." + c.class
+}
+
+func (c attrSelector) String() string {
+ val := c.val
+ if c.operation == "#=" {
+ val = c.regexp.String()
+ } else if c.operation != "" {
+ val = fmt.Sprintf(`"%s"`, val)
+ }
+ return fmt.Sprintf(`[%s%s%s]`, c.key, c.operation, val)
+}
+
+func (c relativePseudoClassSelector) String() string {
+ return fmt.Sprintf(":%s(%s)", c.name, c.match.String())
+}
+func (c containsPseudoClassSelector) String() string {
+ s := "contains"
+ if c.own {
+ s += "Own"
+ }
+ return fmt.Sprintf(`:%s("%s")`, s, c.value)
+}
+func (c regexpPseudoClassSelector) String() string {
+ s := "matches"
+ if c.own {
+ s += "Own"
+ }
+ return fmt.Sprintf(":%s(%s)", s, c.regexp.String())
+}
+func (c nthPseudoClassSelector) String() string {
+ if c.a == 0 && c.b == 1 { // special cases
+ s := ":first-"
+ if c.last {
+ s = ":last-"
+ }
+ if c.ofType {
+ s += "of-type"
+ } else {
+ s += "child"
+ }
+ return s
+ }
+ var name string
+ switch [2]bool{c.last, c.ofType} {
+ case [2]bool{true, true}:
+ name = "nth-last-of-type"
+ case [2]bool{true, false}:
+ name = "nth-last-child"
+ case [2]bool{false, true}:
+ name = "nth-of-type"
+ case [2]bool{false, false}:
+ name = "nth-child"
+ }
+ return fmt.Sprintf(":%s(%dn+%d)", name, c.a, c.b)
+}
+func (c onlyChildPseudoClassSelector) String() string {
+ if c.ofType {
+ return ":only-of-type"
+ }
+ return ":only-child"
+}
+func (c inputPseudoClassSelector) String() string {
+ return ":input"
+}
+func (c emptyElementPseudoClassSelector) String() string {
+ return ":empty"
+}
+func (c rootPseudoClassSelector) String() string {
+ return ":root"
+}
+
+func (c compoundSelector) String() string {
+ if len(c.selectors) == 0 && c.pseudoElement == "" {
+ return "*"
+ }
+ chunks := make([]string, len(c.selectors))
+ for i, sel := range c.selectors {
+ chunks[i] = sel.String()
+ }
+ s := strings.Join(chunks, "")
+ if c.pseudoElement != "" {
+ s += "::" + c.pseudoElement
+ }
+ return s
+}
+
+func (c combinedSelector) String() string {
+ start := c.first.String()
+ if c.second != nil {
+ start += fmt.Sprintf(" %s %s", string(c.combinator), c.second.String())
+ }
+ return start
+}
+
+func (c SelectorGroup) String() string {
+ ck := make([]string, len(c))
+ for i, s := range c {
+ ck[i] = s.String()
+ }
+ return strings.Join(ck, ", ")
+}