diff options
author | techknowlogick <techknowlogick@gitea.io> | 2022-01-14 18:16:05 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-14 18:16:05 -0500 |
commit | 84145e45c50130922fae9055535ab5ea0378e1d4 (patch) | |
tree | fce077a5ae462840bb876ace79aca42abab29ed7 /vendor/github.com/andybalholm/cascadia | |
parent | 2b16ca7c773de278ba01f122dc6f9f43d7534c52 (diff) | |
download | gitea-84145e45c50130922fae9055535ab5ea0378e1d4.tar.gz gitea-84145e45c50130922fae9055535ab5ea0378e1d4.zip |
Remove golang vendored directory (#18277)
* rm go vendor
* fix drone yaml
* add to gitignore
Diffstat (limited to 'vendor/github.com/andybalholm/cascadia')
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/.travis.yml | 14 | ||||
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/LICENSE | 24 | ||||
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/README.md | 9 | ||||
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/go.mod | 5 | ||||
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/parser.go | 838 | ||||
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/selector.go | 938 | ||||
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/serialize.go | 120 | ||||
-rw-r--r-- | vendor/github.com/andybalholm/cascadia/specificity.go | 26 |
8 files changed, 0 insertions, 1974 deletions
diff --git a/vendor/github.com/andybalholm/cascadia/.travis.yml b/vendor/github.com/andybalholm/cascadia/.travis.yml deleted file mode 100644 index 6f227517d6..0000000000 --- a/vendor/github.com/andybalholm/cascadia/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: go - -go: - - 1.3 - - 1.4 - -install: - - go get github.com/andybalholm/cascadia - -script: - - go test -v - -notifications: - email: false diff --git a/vendor/github.com/andybalholm/cascadia/LICENSE b/vendor/github.com/andybalholm/cascadia/LICENSE deleted file mode 100644 index ee5ad35acc..0000000000 --- a/vendor/github.com/andybalholm/cascadia/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -Copyright (c) 2011 Andy Balholm. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/andybalholm/cascadia/README.md b/vendor/github.com/andybalholm/cascadia/README.md deleted file mode 100644 index 26f4c37b36..0000000000 --- a/vendor/github.com/andybalholm/cascadia/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# cascadia - -[![](https://travis-ci.org/andybalholm/cascadia.svg)](https://travis-ci.org/andybalholm/cascadia) - -The Cascadia package implements CSS selectors for use with the parse trees produced by the html package. - -To test CSS selectors without writing Go code, check out [cascadia](https://github.com/suntong/cascadia) the command line tool, a thin wrapper around this package. - -[Refer to godoc here](https://godoc.org/github.com/andybalholm/cascadia). diff --git a/vendor/github.com/andybalholm/cascadia/go.mod b/vendor/github.com/andybalholm/cascadia/go.mod deleted file mode 100644 index 51a330b500..0000000000 --- a/vendor/github.com/andybalholm/cascadia/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module github.com/andybalholm/cascadia - -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 deleted file mode 100644 index c40a39fed1..0000000000 --- a/vendor/github.com/andybalholm/cascadia/parser.go +++ /dev/null @@ -1,838 +0,0 @@ -// Package cascadia is an implementation of CSS selectors. -package cascadia - -import ( - "errors" - "fmt" - "regexp" - "strconv" - "strings" -) - -// a parser for CSS selectors -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. -func (p *parser) parseEscape() (result string, err error) { - if len(p.s) < p.i+2 || p.s[p.i] != '\\' { - return "", errors.New("invalid escape sequence") - } - - start := p.i + 1 - c := p.s[start] - switch { - case c == '\r' || c == '\n' || c == '\f': - return "", errors.New("escaped line ending outside string") - case hexDigit(c): - // unicode escape (hex) - var i int - 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) - if len(p.s) > i { - switch p.s[i] { - case '\r': - i++ - if len(p.s) > i && p.s[i] == '\n' { - i++ - } - case ' ', '\t', '\n', '\f': - i++ - } - } - p.i = i - return string(rune(v)), nil - } - - // Return the literal character after the backslash. - result = p.s[start : start+1] - p.i += 2 - return result, nil -} - -// toLowerASCII returns s with all ASCII capital letters lowercased. -func toLowerASCII(s string) string { - var b []byte - for i := 0; i < len(s); i++ { - if c := s[i]; 'A' <= c && c <= 'Z' { - if b == nil { - b = make([]byte, len(s)) - copy(b, s) - } - b[i] = s[i] + ('a' - 'A') - } - } - - if b == nil { - return s - } - - return string(b) -} - -func hexDigit(c byte) bool { - return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' -} - -// nameStart returns whether c can be the first character of an identifier -// (not counting an initial hyphen, or an escape sequence). -func nameStart(c byte) bool { - return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c > 127 -} - -// nameChar returns whether c can be a character within an identifier -// (not counting an escape sequence). -func nameChar(c byte) bool { - return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c > 127 || - c == '-' || '0' <= c && c <= '9' -} - -// parseIdentifier parses an identifier. -func (p *parser) parseIdentifier() (result string, err error) { - startingDash := false - if len(p.s) > p.i && p.s[p.i] == '-' { - startingDash = true - p.i++ - } - - if len(p.s) <= p.i { - return "", errors.New("expected identifier, found EOF instead") - } - - if c := p.s[p.i]; !(nameStart(c) || c == '\\') { - return "", fmt.Errorf("expected identifier, found %c instead", c) - } - - result, err = p.parseName() - if startingDash && err == nil { - result = "-" + result - } - return -} - -// parseName parses a name (which is like an identifier, but doesn't have -// extra restrictions on the first character). -func (p *parser) parseName() (result string, err error) { - i := p.i -loop: - for i < len(p.s) { - c := p.s[i] - switch { - case nameChar(c): - start := i - for i < len(p.s) && nameChar(p.s[i]) { - i++ - } - result += p.s[start:i] - case c == '\\': - p.i = i - val, err := p.parseEscape() - if err != nil { - return "", err - } - i = p.i - result += val - default: - break loop - } - } - - if result == "" { - return "", errors.New("expected name, found EOF instead") - } - - p.i = i - return result, nil -} - -// parseString parses a single- or double-quoted string. -func (p *parser) parseString() (result string, err error) { - i := p.i - if len(p.s) < i+2 { - return "", errors.New("expected string, found EOF instead") - } - - quote := p.s[i] - i++ - -loop: - for i < len(p.s) { - switch p.s[i] { - case '\\': - if len(p.s) > i+1 { - switch c := p.s[i+1]; c { - case '\r': - if len(p.s) > i+2 && p.s[i+2] == '\n' { - i += 3 - continue loop - } - fallthrough - case '\n', '\f': - i += 2 - continue loop - } - } - p.i = i - val, err := p.parseEscape() - if err != nil { - return "", err - } - i = p.i - result += val - case quote: - break loop - case '\r', '\n', '\f': - return "", errors.New("unexpected end of line in string") - default: - start := i - for i < len(p.s) { - if c := p.s[i]; c == quote || c == '\\' || c == '\r' || c == '\n' || c == '\f' { - break - } - i++ - } - result += p.s[start:i] - } - } - - if i >= len(p.s) { - return "", errors.New("EOF in string") - } - - // Consume the final quote. - i++ - - p.i = i - return result, nil -} - -// parseRegex parses a regular expression; the end is defined by encountering an -// unmatched closing ')' or ']' which is not consumed -func (p *parser) parseRegex() (rx *regexp.Regexp, err error) { - i := p.i - if len(p.s) < i+2 { - return nil, errors.New("expected regular expression, found EOF instead") - } - - // number of open parens or brackets; - // when it becomes negative, finished parsing regex - open := 0 - -loop: - for i < len(p.s) { - switch p.s[i] { - case '(', '[': - open++ - case ')', ']': - open-- - if open < 0 { - break loop - } - } - i++ - } - - if i >= len(p.s) { - return nil, errors.New("EOF in regular expression") - } - rx, err = regexp.Compile(p.s[p.i:i]) - p.i = i - return rx, err -} - -// skipWhitespace consumes whitespace characters and comments. -// It returns true if there was actually anything to skip. -func (p *parser) skipWhitespace() bool { - i := p.i - for i < len(p.s) { - switch p.s[i] { - case ' ', '\t', '\r', '\n', '\f': - i++ - continue - case '/': - if strings.HasPrefix(p.s[i:], "/*") { - end := strings.Index(p.s[i+len("/*"):], "*/") - if end != -1 { - i += end + len("/**/") - continue - } - } - } - break - } - - if i > p.i { - p.i = i - return true - } - - return false -} - -// consumeParenthesis consumes an opening parenthesis and any following -// whitespace. It returns true if there was actually a parenthesis to skip. -func (p *parser) consumeParenthesis() bool { - if p.i < len(p.s) && p.s[p.i] == '(' { - p.i++ - p.skipWhitespace() - return true - } - return false -} - -// consumeClosingParenthesis consumes a closing parenthesis and any preceding -// whitespace. It returns true if there was actually a parenthesis to skip. -func (p *parser) consumeClosingParenthesis() bool { - i := p.i - p.skipWhitespace() - if p.i < len(p.s) && p.s[p.i] == ')' { - p.i++ - return true - } - p.i = i - return false -} - -// parseTypeSelector parses a type selector (one that matches by tag name). -func (p *parser) parseTypeSelector() (result tagSelector, err error) { - tag, err := p.parseIdentifier() - if err != nil { - return - } - return tagSelector{tag: toLowerASCII(tag)}, nil -} - -// parseIDSelector parses a selector that matches by id attribute. -func (p *parser) parseIDSelector() (idSelector, error) { - if p.i >= len(p.s) { - return idSelector{}, fmt.Errorf("expected id selector (#id), found EOF instead") - } - if p.s[p.i] != '#' { - return idSelector{}, fmt.Errorf("expected id selector (#id), found '%c' instead", p.s[p.i]) - } - - p.i++ - id, err := p.parseName() - if err != nil { - return idSelector{}, err - } - - return idSelector{id: id}, nil -} - -// parseClassSelector parses a selector that matches by class attribute. -func (p *parser) parseClassSelector() (classSelector, error) { - if p.i >= len(p.s) { - return classSelector{}, fmt.Errorf("expected class selector (.class), found EOF instead") - } - if p.s[p.i] != '.' { - return classSelector{}, fmt.Errorf("expected class selector (.class), found '%c' instead", p.s[p.i]) - } - - p.i++ - class, err := p.parseIdentifier() - if err != nil { - return classSelector{}, err - } - - return classSelector{class: class}, nil -} - -// parseAttributeSelector parses a selector that matches by attribute value. -func (p *parser) parseAttributeSelector() (attrSelector, error) { - if p.i >= len(p.s) { - return attrSelector{}, fmt.Errorf("expected attribute selector ([attribute]), found EOF instead") - } - if p.s[p.i] != '[' { - return attrSelector{}, fmt.Errorf("expected attribute selector ([attribute]), found '%c' instead", p.s[p.i]) - } - - p.i++ - p.skipWhitespace() - key, err := p.parseIdentifier() - if err != nil { - return attrSelector{}, err - } - key = toLowerASCII(key) - - p.skipWhitespace() - if p.i >= len(p.s) { - return attrSelector{}, errors.New("unexpected EOF in attribute selector") - } - - if p.s[p.i] == ']' { - p.i++ - return attrSelector{key: key, operation: ""}, nil - } - - if p.i+2 >= len(p.s) { - return attrSelector{}, errors.New("unexpected EOF in attribute selector") - } - - op := p.s[p.i : p.i+2] - if op[0] == '=' { - op = "=" - } else if op[1] != '=' { - return attrSelector{}, fmt.Errorf(`expected equality operator, found "%s" instead`, op) - } - p.i += len(op) - - p.skipWhitespace() - if p.i >= len(p.s) { - return attrSelector{}, errors.New("unexpected EOF in attribute selector") - } - var val string - var rx *regexp.Regexp - if op == "#=" { - rx, err = p.parseRegex() - } else { - switch p.s[p.i] { - case '\'', '"': - val, err = p.parseString() - default: - val, err = p.parseIdentifier() - } - } - if err != nil { - return attrSelector{}, err - } - - p.skipWhitespace() - if p.i >= len(p.s) { - return attrSelector{}, errors.New("unexpected EOF in attribute selector") - } - if p.s[p.i] != ']' { - return attrSelector{}, fmt.Errorf("expected ']', found '%c' instead", p.s[p.i]) - } - p.i++ - - switch op { - case "=", "!=", "~=", "|=", "^=", "$=", "*=", "#=": - return attrSelector{key: key, val: val, operation: op, regexp: rx}, nil - default: - return attrSelector{}, fmt.Errorf("attribute operator %q is not supported", op) - } -} - -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) 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") - } - if 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++ - } - - name, err := p.parseIdentifier() - if err != nil { - 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 - } - sel, parseErr := p.parseSelectorGroup() - if parseErr != nil { - return out, "", parseErr - } - if !p.consumeClosingParenthesis() { - return out, "", errExpectedClosingParenthesis - } - - out = relativePseudoClassSelector{name: name, match: sel} - - case "contains", "containsown": - if !p.consumeParenthesis() { - return out, "", errExpectedParenthesis - } - if p.i == len(p.s) { - return out, "", errUnmatchedParenthesis - } - var val string - switch p.s[p.i] { - case '\'', '"': - val, err = p.parseString() - default: - val, err = p.parseIdentifier() - } - if err != nil { - return out, "", err - } - val = strings.ToLower(val) - p.skipWhitespace() - if p.i >= len(p.s) { - return out, "", errors.New("unexpected EOF in pseudo selector") - } - if !p.consumeClosingParenthesis() { - return out, "", errExpectedClosingParenthesis - } - - out = containsPseudoClassSelector{own: name == "containsown", value: val} - - case "matches", "matchesown": - if !p.consumeParenthesis() { - return out, "", errExpectedParenthesis - } - rx, err := p.parseRegex() - if err != nil { - return out, "", err - } - if p.i >= len(p.s) { - return out, "", errors.New("unexpected EOF in pseudo selector") - } - if !p.consumeClosingParenthesis() { - 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 - } - a, b, err := p.parseNth() - if err != nil { - return out, "", err - } - if !p.consumeClosingParenthesis() { - return out, "", errExpectedClosingParenthesis - } - last := name == "nth-last-child" || name == "nth-last-of-type" - ofType := name == "nth-of-type" || name == "nth-last-of-type" - out = nthPseudoClassSelector{a: a, b: b, last: last, ofType: ofType} - - case "first-child": - out = nthPseudoClassSelector{a: 0, b: 1, ofType: false, last: false} - case "last-child": - out = nthPseudoClassSelector{a: 0, b: 1, ofType: false, last: true} - case "first-of-type": - out = nthPseudoClassSelector{a: 0, b: 1, ofType: true, last: false} - case "last-of-type": - out = nthPseudoClassSelector{a: 0, b: 1, ofType: true, last: true} - case "only-child": - out = onlyChildPseudoClassSelector{ofType: false} - case "only-of-type": - out = onlyChildPseudoClassSelector{ofType: true} - case "input": - out = inputPseudoClassSelector{} - case "empty": - out = emptyElementPseudoClassSelector{} - case "root": - out = rootPseudoClassSelector{} - case "after", "backdrop", "before", "cue", "first-letter", "first-line", "grammar-error", "marker", "placeholder", "selection", "spelling-error": - return nil, name, nil - default: - return out, "", fmt.Errorf("unknown pseudoclass or pseudoelement :%s", name) - } - return -} - -// parseInteger parses a decimal integer. -func (p *parser) parseInteger() (int, error) { - i := p.i - start := i - for i < len(p.s) && '0' <= p.s[i] && p.s[i] <= '9' { - i++ - } - if i == start { - return 0, errors.New("expected integer, but didn't find it") - } - p.i = i - - val, err := strconv.Atoi(p.s[start:i]) - if err != nil { - return 0, err - } - - return val, nil -} - -// parseNth parses the argument for :nth-child (normally of the form an+b). -func (p *parser) parseNth() (a, b int, err error) { - // initial state - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '-': - p.i++ - goto negativeA - case '+': - p.i++ - goto positiveA - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - goto positiveA - case 'n', 'N': - a = 1 - p.i++ - goto readN - case 'o', 'O', 'e', 'E': - id, nameErr := p.parseName() - if nameErr != nil { - return 0, 0, nameErr - } - id = toLowerASCII(id) - if id == "odd" { - return 2, 1, nil - } - if id == "even" { - return 2, 0, nil - } - return 0, 0, fmt.Errorf("expected 'odd' or 'even', but found '%s' instead", id) - default: - goto invalid - } - -positiveA: - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - a, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - goto readA - case 'n', 'N': - a = 1 - p.i++ - goto readN - default: - goto invalid - } - -negativeA: - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - a, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - a = -a - goto readA - case 'n', 'N': - a = -1 - p.i++ - goto readN - default: - goto invalid - } - -readA: - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case 'n', 'N': - p.i++ - goto readN - default: - // The number we read as a is actually b. - return 0, a, nil - } - -readN: - p.skipWhitespace() - if p.i >= len(p.s) { - goto eof - } - switch p.s[p.i] { - case '+': - p.i++ - p.skipWhitespace() - b, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - return a, b, nil - case '-': - p.i++ - p.skipWhitespace() - b, err = p.parseInteger() - if err != nil { - return 0, 0, err - } - return a, -b, nil - default: - return a, 0, nil - } - -eof: - return 0, 0, errors.New("unexpected EOF while attempting to parse expression of form an+b") - -invalid: - return 0, 0, errors.New("unexpected character while attempting to parse expression of form an+b") -} - -// parseSimpleSelectorSequence parses a selector sequence that applies to -// a single element. -func (p *parser) parseSimpleSelectorSequence() (Sel, error) { - var selectors []Sel - - if p.i >= len(p.s) { - return nil, errors.New("expected selector, found EOF instead") - } - - switch p.s[p.i] { - case '*': - // It's the universal selector. Just skip over it, since it doesn't affect the meaning. - p.i++ - case '#', '.', '[', ':': - // There's no type selector. Wait to process the other till the main loop. - default: - r, err := p.parseTypeSelector() - if err != nil { - return nil, err - } - selectors = append(selectors, r) - } - - var pseudoElement string -loop: - for p.i < len(p.s) { - var ( - ns Sel - newPseudoElement string - err error - ) - switch p.s[p.i] { - case '#': - ns, err = p.parseIDSelector() - case '.': - ns, err = p.parseClassSelector() - case '[': - ns, err = p.parseAttributeSelector() - case ':': - 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) - } - - } - if len(selectors) == 1 && pseudoElement == "" { // no need wrap the selectors in compoundSelector - return selectors[0], nil - } - return compoundSelector{selectors: selectors, pseudoElement: pseudoElement}, nil -} - -// parseSelector parses a selector that may include combinators. -func (p *parser) parseSelector() (Sel, error) { - p.skipWhitespace() - result, err := p.parseSimpleSelectorSequence() - if err != nil { - return nil, err - } - - for { - var ( - combinator byte - c Sel - ) - if p.skipWhitespace() { - combinator = ' ' - } - if p.i >= len(p.s) { - return result, nil - } - - switch p.s[p.i] { - case '+', '>', '~': - combinator = p.s[p.i] - p.i++ - p.skipWhitespace() - case ',', ')': - // These characters can't begin a selector, but they can legally occur after one. - return result, nil - } - - if combinator == 0 { - return result, nil - } - - c, err = p.parseSimpleSelectorSequence() - if err != nil { - return nil, err - } - result = combinedSelector{first: result, combinator: combinator, second: c} - } -} - -// parseSelectorGroup parses a group of selectors, separated by commas. -func (p *parser) parseSelectorGroup() (SelectorGroup, error) { - current, err := p.parseSelector() - if err != nil { - return nil, err - } - result := SelectorGroup{current} - - for p.i < len(p.s) { - if p.s[p.i] != ',' { - break - } - p.i++ - c, err := p.parseSelector() - if err != nil { - return nil, err - } - result = append(result, c) - } - return result, nil -} diff --git a/vendor/github.com/andybalholm/cascadia/selector.go b/vendor/github.com/andybalholm/cascadia/selector.go deleted file mode 100644 index e2a6dc4be1..0000000000 --- a/vendor/github.com/andybalholm/cascadia/selector.go +++ /dev/null @@ -1,938 +0,0 @@ -package cascadia - -import ( - "bytes" - "fmt" - "regexp" - "strings" - - "golang.org/x/net/html" -) - -// Matcher is the interface for basic selector functionality. -// Match returns whether a selector matches n. -type Matcher interface { - Match(n *html.Node) bool -} - -// Sel is the interface for all the functionality provided by selectors. -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. Use `ParseWithPseudoElement` -// if you need support for pseudo-elements. -func Parse(sel string) (Sel, error) { - p := &parser{s: sel} - 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 -} - -// 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() - 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 -} - -// 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 -// more idiomatic interfaces Sel and Matcher. -type Selector func(*html.Node) bool - -// Compile parses a selector and returns, if successful, a Selector object -// that can be used to match against html.Node objects. -func Compile(sel string) (Selector, error) { - compiled, err := ParseGroup(sel) - if err != nil { - return nil, err - } - - return Selector(compiled.Match), nil -} - -// MustCompile is like Compile, but panics instead of returning an error. -func MustCompile(sel string) Selector { - compiled, err := Compile(sel) - if err != nil { - panic(err) - } - return compiled -} - -// MatchAll returns a slice of the nodes that match the selector, -// from n and its children. -func (s Selector) MatchAll(n *html.Node) []*html.Node { - return s.matchAllInto(n, nil) -} - -func (s Selector) matchAllInto(n *html.Node, storage []*html.Node) []*html.Node { - if s(n) { - storage = append(storage, n) - } - - for child := n.FirstChild; child != nil; child = child.NextSibling { - storage = s.matchAllInto(child, storage) - } - - return storage -} - -func queryInto(n *html.Node, m Matcher, storage []*html.Node) []*html.Node { - for child := n.FirstChild; child != nil; child = child.NextSibling { - if m.Match(child) { - storage = append(storage, child) - } - storage = queryInto(child, m, storage) - } - - return storage -} - -// QueryAll returns a slice of all the nodes that match m, from the descendants -// of n. -func QueryAll(n *html.Node, m Matcher) []*html.Node { - return queryInto(n, m, nil) -} - -// Match returns true if the node matches the selector. -func (s Selector) Match(n *html.Node) bool { - return s(n) -} - -// MatchFirst returns the first node that matches s, from n and its children. -func (s Selector) MatchFirst(n *html.Node) *html.Node { - if s.Match(n) { - return n - } - - for c := n.FirstChild; c != nil; c = c.NextSibling { - m := s.MatchFirst(c) - if m != nil { - return m - } - } - return nil -} - -// Query returns the first node that matches m, from the descendants of n. -// If none matches, it returns nil. -func Query(n *html.Node, m Matcher) *html.Node { - for c := n.FirstChild; c != nil; c = c.NextSibling { - if m.Match(c) { - return c - } - if matched := Query(c, m); matched != nil { - return matched - } - } - - return nil -} - -// Filter returns the nodes in nodes that match the selector. -func (s Selector) Filter(nodes []*html.Node) (result []*html.Node) { - for _, n := range nodes { - if s(n) { - result = append(result, n) - } - } - return result -} - -// Filter returns the nodes that match m. -func Filter(nodes []*html.Node, m Matcher) (result []*html.Node) { - for _, n := range nodes { - if m.Match(n) { - result = append(result, n) - } - } - return result -} - -type tagSelector struct { - tag string -} - -// Matches elements with a given tag name. -func (t tagSelector) Match(n *html.Node) bool { - return n.Type == html.ElementNode && n.Data == t.tag -} - -func (c tagSelector) Specificity() Specificity { - return Specificity{0, 0, 1} -} - -func (c tagSelector) PseudoElement() string { - return "" -} - -type classSelector struct { - class string -} - -// Matches elements by class attribute. -func (t classSelector) Match(n *html.Node) bool { - return matchAttribute(n, "class", func(s string) bool { - return matchInclude(t.class, s) - }) -} - -func (c classSelector) Specificity() Specificity { - return Specificity{0, 1, 0} -} - -func (c classSelector) PseudoElement() string { - return "" -} - -type idSelector struct { - id string -} - -// Matches elements by id attribute. -func (t idSelector) Match(n *html.Node) bool { - return matchAttribute(n, "id", func(s string) bool { - return s == t.id - }) -} - -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 -} - -// Matches elements by attribute value. -func (t attrSelector) Match(n *html.Node) bool { - switch t.operation { - case "": - return matchAttribute(n, t.key, func(string) bool { return true }) - case "=": - return matchAttribute(n, t.key, func(s string) bool { return s == t.val }) - case "!=": - return attributeNotEqualMatch(t.key, t.val, n) - case "~=": - // matches elements where the attribute named key is a whitespace-separated list that includes val. - return matchAttribute(n, t.key, func(s string) bool { return matchInclude(t.val, s) }) - case "|=": - return attributeDashMatch(t.key, t.val, n) - case "^=": - return attributePrefixMatch(t.key, t.val, n) - case "$=": - return attributeSuffixMatch(t.key, t.val, n) - case "*=": - return attributeSubstringMatch(t.key, t.val, n) - case "#=": - return attributeRegexMatch(t.key, t.regexp, n) - default: - panic(fmt.Sprintf("unsuported operation : %s", t.operation)) - } -} - -// matches elements where the attribute named key satisifes the function f. -func matchAttribute(n *html.Node, key string, f func(string) bool) bool { - if n.Type != html.ElementNode { - return false - } - for _, a := range n.Attr { - if a.Key == key && f(a.Val) { - return true - } - } - return false -} - -// attributeNotEqualMatch matches elements where -// the attribute named key does not have the value val. -func attributeNotEqualMatch(key, val string, n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - for _, a := range n.Attr { - if a.Key == key && a.Val == val { - return false - } - } - return true -} - -// returns true if s is a whitespace-separated list that includes val. -func matchInclude(val, s string) bool { - for s != "" { - i := strings.IndexAny(s, " \t\r\n\f") - if i == -1 { - return s == val - } - if s[:i] == val { - return true - } - s = s[i+1:] - } - return false -} - -// matches elements where the attribute named key equals val or starts with val plus a hyphen. -func attributeDashMatch(key, val string, n *html.Node) bool { - return matchAttribute(n, key, - func(s string) bool { - if s == val { - return true - } - if len(s) <= len(val) { - return false - } - if s[:len(val)] == val && s[len(val)] == '-' { - return true - } - return false - }) -} - -// attributePrefixMatch returns a Selector that matches elements where -// the attribute named key starts with val. -func attributePrefixMatch(key, val string, n *html.Node) bool { - return matchAttribute(n, key, - func(s string) bool { - if strings.TrimSpace(s) == "" { - return false - } - return strings.HasPrefix(s, val) - }) -} - -// attributeSuffixMatch matches elements where -// the attribute named key ends with val. -func attributeSuffixMatch(key, val string, n *html.Node) bool { - return matchAttribute(n, key, - func(s string) bool { - if strings.TrimSpace(s) == "" { - return false - } - return strings.HasSuffix(s, val) - }) -} - -// attributeSubstringMatch matches nodes where -// the attribute named key contains val. -func attributeSubstringMatch(key, val string, n *html.Node) bool { - return matchAttribute(n, key, - func(s string) bool { - if strings.TrimSpace(s) == "" { - return false - } - return strings.Contains(s, val) - }) -} - -// attributeRegexMatch matches nodes where -// the attribute named key matches the regular expression rx -func attributeRegexMatch(key string, rx *regexp.Regexp, n *html.Node) bool { - return matchAttribute(n, key, - func(s string) bool { - return rx.MatchString(s) - }) -} - -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 - -type relativePseudoClassSelector struct { - name string // one of "not", "has", "haschild" - match SelectorGroup -} - -func (s relativePseudoClassSelector) Match(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - switch s.name { - case "not": - // matches elements that do not match a. - return !s.match.Match(n) - case "has": - // matches elements with any descendant that matches a. - return hasDescendantMatch(n, s.match) - case "haschild": - // matches elements with a child that matches a. - return hasChildMatch(n, s.match) - default: - panic(fmt.Sprintf("unsupported relative pseudo class selector : %s", s.name)) - } -} - -// hasChildMatch returns whether n has any child that matches a. -func hasChildMatch(n *html.Node, a Matcher) bool { - for c := n.FirstChild; c != nil; c = c.NextSibling { - if a.Match(c) { - return true - } - } - return false -} - -// hasDescendantMatch performs a depth-first search of n's descendants, -// testing whether any of them match a. It returns true as soon as a match is -// found, or false if no match is found. -func hasDescendantMatch(n *html.Node, a Matcher) bool { - for c := n.FirstChild; c != nil; c = c.NextSibling { - if a.Match(c) || (c.Type == html.ElementNode && hasDescendantMatch(c, a)) { - return true - } - } - return false -} - -// Specificity returns the specificity of the most specific selectors -// in the pseudo-class arguments. -// See https://www.w3.org/TR/selectors/#specificity-rules -func (s relativePseudoClassSelector) Specificity() Specificity { - var max Specificity - for _, sel := range s.match { - newSpe := sel.Specificity() - if max.Less(newSpe) { - max = newSpe - } - } - return max -} - -func (c relativePseudoClassSelector) PseudoElement() string { - return "" -} - -type containsPseudoClassSelector struct { - own bool - value string -} - -func (s containsPseudoClassSelector) Match(n *html.Node) bool { - var text string - if s.own { - // matches nodes that directly contain the given text - text = strings.ToLower(nodeOwnText(n)) - } else { - // matches nodes that contain the given text. - text = strings.ToLower(nodeText(n)) - } - return strings.Contains(text, s.value) -} - -func (s containsPseudoClassSelector) Specificity() Specificity { - return Specificity{0, 1, 0} -} - -func (c containsPseudoClassSelector) PseudoElement() string { - return "" -} - -type regexpPseudoClassSelector struct { - own bool - regexp *regexp.Regexp -} - -func (s regexpPseudoClassSelector) Match(n *html.Node) bool { - var text string - if s.own { - // matches nodes whose text directly matches the specified regular expression - text = nodeOwnText(n) - } else { - // matches nodes whose text matches the specified regular expression - text = nodeText(n) - } - return s.regexp.MatchString(text) -} - -// writeNodeText writes the text contained in n and its descendants to b. -func writeNodeText(n *html.Node, b *bytes.Buffer) { - switch n.Type { - case html.TextNode: - b.WriteString(n.Data) - case html.ElementNode: - for c := n.FirstChild; c != nil; c = c.NextSibling { - writeNodeText(c, b) - } - } -} - -// nodeText returns the text contained in n and its descendants. -func nodeText(n *html.Node) string { - var b bytes.Buffer - writeNodeText(n, &b) - return b.String() -} - -// nodeOwnText returns the contents of the text nodes that are direct -// children of n. -func nodeOwnText(n *html.Node) string { - var b bytes.Buffer - for c := n.FirstChild; c != nil; c = c.NextSibling { - if c.Type == html.TextNode { - b.WriteString(c.Data) - } - } - return b.String() -} - -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 -} - -func (s nthPseudoClassSelector) Match(n *html.Node) bool { - if s.a == 0 { - if s.last { - return simpleNthLastChildMatch(s.b, s.ofType, n) - } else { - return simpleNthChildMatch(s.b, s.ofType, n) - } - } - return nthChildMatch(s.a, s.b, s.last, s.ofType, n) -} - -// nthChildMatch implements :nth-child(an+b). -// If last is true, implements :nth-last-child instead. -// If ofType is true, implements :nth-of-type instead. -func nthChildMatch(a, b int, last, ofType bool, n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - i := -1 - count := 0 - for c := parent.FirstChild; c != nil; c = c.NextSibling { - if (c.Type != html.ElementNode) || (ofType && c.Data != n.Data) { - continue - } - count++ - if c == n { - i = count - if !last { - break - } - } - } - - if i == -1 { - // This shouldn't happen, since n should always be one of its parent's children. - return false - } - - if last { - i = count - i + 1 - } - - i -= b - if a == 0 { - return i == 0 - } - - return i%a == 0 && i/a >= 0 -} - -// simpleNthChildMatch implements :nth-child(b). -// If ofType is true, implements :nth-of-type instead. -func simpleNthChildMatch(b int, ofType bool, n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - count := 0 - for c := parent.FirstChild; c != nil; c = c.NextSibling { - if c.Type != html.ElementNode || (ofType && c.Data != n.Data) { - continue - } - count++ - if c == n { - return count == b - } - if count >= b { - return false - } - } - return false -} - -// simpleNthLastChildMatch implements :nth-last-child(b). -// If ofType is true, implements :nth-last-of-type instead. -func simpleNthLastChildMatch(b int, ofType bool, n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - count := 0 - for c := parent.LastChild; c != nil; c = c.PrevSibling { - if c.Type != html.ElementNode || (ofType && c.Data != n.Data) { - continue - } - count++ - if c == n { - return count == b - } - if count >= b { - return false - } - } - return false -} - -// Specificity for nth-child pseudo-class. -// Does not support a list of selectors -func (s nthPseudoClassSelector) Specificity() Specificity { - return Specificity{0, 1, 0} -} - -func (c nthPseudoClassSelector) PseudoElement() string { - return "" -} - -type onlyChildPseudoClassSelector struct { - ofType bool -} - -// Match implements :only-child. -// If `ofType` is true, it implements :only-of-type instead. -func (s onlyChildPseudoClassSelector) Match(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - parent := n.Parent - if parent == nil { - return false - } - - if parent.Type == html.DocumentNode { - return false - } - - count := 0 - for c := parent.FirstChild; c != nil; c = c.NextSibling { - if (c.Type != html.ElementNode) || (s.ofType && c.Data != n.Data) { - continue - } - count++ - if count > 1 { - return false - } - } - - return count == 1 -} - -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. -func (s inputPseudoClassSelector) Match(n *html.Node) bool { - return n.Type == html.ElementNode && (n.Data == "input" || n.Data == "select" || n.Data == "textarea" || n.Data == "button") -} - -func (s inputPseudoClassSelector) Specificity() Specificity { - return Specificity{0, 1, 0} -} - -func (c inputPseudoClassSelector) PseudoElement() string { - return "" -} - -type emptyElementPseudoClassSelector struct{} - -// Matches empty elements. -func (s emptyElementPseudoClassSelector) Match(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - - for c := n.FirstChild; c != nil; c = c.NextSibling { - switch c.Type { - case html.ElementNode, html.TextNode: - return false - } - } - - return true -} - -func (s emptyElementPseudoClassSelector) Specificity() Specificity { - return Specificity{0, 1, 0} -} - -func (c emptyElementPseudoClassSelector) PseudoElement() string { - return "" -} - -type rootPseudoClassSelector struct{} - -// Match implements :root -func (s rootPseudoClassSelector) Match(n *html.Node) bool { - if n.Type != html.ElementNode { - return false - } - if n.Parent == nil { - return false - } - return n.Parent.Type == html.DocumentNode -} - -func (s rootPseudoClassSelector) Specificity() Specificity { - return Specificity{0, 1, 0} -} - -func (c rootPseudoClassSelector) PseudoElement() string { - return "" -} - -type compoundSelector struct { - selectors []Sel - pseudoElement string -} - -// Matches elements if each sub-selectors matches. -func (t compoundSelector) Match(n *html.Node) bool { - if len(t.selectors) == 0 { - return n.Type == html.ElementNode - } - - for _, sel := range t.selectors { - if !sel.Match(n) { - return false - } - } - return true -} - -func (s compoundSelector) Specificity() Specificity { - var out 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 - second Sel -} - -func (t combinedSelector) Match(n *html.Node) bool { - if t.first == nil { - return false // maybe we should panic - } - switch t.combinator { - case 0: - return t.first.Match(n) - case ' ': - return descendantMatch(t.first, t.second, n) - case '>': - return childMatch(t.first, t.second, n) - case '+': - return siblingMatch(t.first, t.second, true, n) - case '~': - return siblingMatch(t.first, t.second, false, n) - default: - panic("unknown combinator") - } -} - -// matches an element if it matches d and has an ancestor that matches a. -func descendantMatch(a, d Matcher, n *html.Node) bool { - if !d.Match(n) { - return false - } - - for p := n.Parent; p != nil; p = p.Parent { - if a.Match(p) { - return true - } - } - - return false -} - -// matches an element if it matches d and its parent matches a. -func childMatch(a, d Matcher, n *html.Node) bool { - return d.Match(n) && n.Parent != nil && a.Match(n.Parent) -} - -// matches an element if it matches s2 and is preceded by an element that matches s1. -// If adjacent is true, the sibling must be immediately before the element. -func siblingMatch(s1, s2 Matcher, adjacent bool, n *html.Node) bool { - if !s2.Match(n) { - return false - } - - if adjacent { - for n = n.PrevSibling; n != nil; n = n.PrevSibling { - if n.Type == html.TextNode || n.Type == html.CommentNode { - continue - } - return s1.Match(n) - } - return false - } - - // Walk backwards looking for element that matches s1 - for c := n.PrevSibling; c != nil; c = c.PrevSibling { - if s1.Match(c) { - return true - } - } - - return false -} - -func (s combinedSelector) Specificity() Specificity { - spec := s.first.Specificity() - if s.second != nil { - spec = spec.Add(s.second.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 - -// Match returns true if the node matches one of the single selectors. -func (s SelectorGroup) Match(n *html.Node) bool { - for _, sel := range s { - if sel.Match(n) { - return true - } - } - return false -} diff --git a/vendor/github.com/andybalholm/cascadia/serialize.go b/vendor/github.com/andybalholm/cascadia/serialize.go deleted file mode 100644 index f15b079527..0000000000 --- a/vendor/github.com/andybalholm/cascadia/serialize.go +++ /dev/null @@ -1,120 +0,0 @@ -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, ", ") -} diff --git a/vendor/github.com/andybalholm/cascadia/specificity.go b/vendor/github.com/andybalholm/cascadia/specificity.go deleted file mode 100644 index 8db864f9be..0000000000 --- a/vendor/github.com/andybalholm/cascadia/specificity.go +++ /dev/null @@ -1,26 +0,0 @@ -package cascadia - -// Specificity is the CSS specificity as defined in -// https://www.w3.org/TR/selectors/#specificity-rules -// with the convention Specificity = [A,B,C]. -type Specificity [3]int - -// returns `true` if s < other (strictly), false otherwise -func (s Specificity) Less(other Specificity) bool { - for i := range s { - if s[i] < other[i] { - return true - } - if s[i] > other[i] { - return false - } - } - return false -} - -func (s Specificity) Add(other Specificity) Specificity { - for i, sp := range other { - s[i] += sp - } - return s -} |