diff --git a/.gitignore b/.gitignore index d1d59c6f..433818fa 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ cf *.out .vscode +bin diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..a285926e --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +#!make + +all: build + +.PHONY: vet +vet: + go vet ./... + +.PHONY: fmt +fmt: + go fmt ./... + +.PHONY: clean +clean: + rm -rf ./bin/* + +.PHONY: build +build: clean fmt + mkdir -p ./bin/ + go build -o ./bin/cf ./cf.go + +.PHONY: run +run: clean fmt vet + go run ./... + +.PHONY: test +test: vet + go test -v -failfast ./... diff --git a/client/client.go b/client/client.go index 7d8d68da..78de04b3 100644 --- a/client/client.go +++ b/client/client.go @@ -9,7 +9,8 @@ import ( "path/filepath" "github.com/fatih/color" - "github.com/xalanq/cf-tool/cookiejar" + // "github.com/xalanq/cf-tool/cookiejar" + "net/http/cookiejar" ) // Client codeforces client diff --git a/client/langs.go b/client/langs.go index b09c69fd..f62eedd4 100644 --- a/client/langs.go +++ b/client/langs.go @@ -2,7 +2,8 @@ package client // Langs generated by // ^[\s\S]*?value="(.+?)"[\s\S]*?>([\s\S]+?)<[\s\S]*?$ -// "\1": "\2", +// +// "\1": "\2", var Langs = map[string]string{ "43": "GNU GCC C11 5.1.0", "52": "Clang++17 Diagnostics", diff --git a/client/login.go b/client/login.go index bb7f9d8d..2286157e 100644 --- a/client/login.go +++ b/client/login.go @@ -14,7 +14,9 @@ import ( "syscall" "github.com/fatih/color" - "github.com/xalanq/cf-tool/cookiejar" + // "github.com/xalanq/cf-tool/cookiejar" + "net/http/cookiejar" + "github.com/xalanq/cf-tool/util" "golang.org/x/crypto/ssh/terminal" ) diff --git a/client/parse.go b/client/parse.go index 382b7345..f1df9839 100644 --- a/client/parse.go +++ b/client/parse.go @@ -11,13 +11,14 @@ import ( "strings" "sync" - "github.com/xalanq/cf-tool/util" - - "github.com/k0kubun/go-ansi" - + "github.com/draychev/go-toolbox/pkg/logger" "github.com/fatih/color" + "github.com/k0kubun/go-ansi" + "github.com/xalanq/cf-tool/util" ) +var log = logger.NewPretty("client") + func findSample(body []byte) (input [][]byte, output [][]byte, err error) { irg := regexp.MustCompile(`class="input"[\s\S]*?
([\s\S]*?)`) org := regexp.MustCompile(`class="output"[\s\S]*?
([\s\S]*?)`) @@ -123,13 +124,14 @@ func (c *Client) Parse(info Info) (problems []string, paths []string, err error) go func(problemID, path string) { defer wg.Done() mu.Lock() - fmt.Printf("Parsing %v\n", problemID) + fmt.Printf("Parsing contest:%s, problem:%v into %s\n", info.ContestID, problemID, path) mu.Unlock() - err = os.MkdirAll(path, os.ModePerm) - if err != nil { + if err = os.MkdirAll(path, os.ModePerm); err != nil { + log.Error().Err(err).Msgf("Error creating directory %s", path) return } + log.Debug().Msgf("Created directory: %s", path) URL := fmt.Sprintf(urlFormatter, problemID) samples, standardIO, err := c.ParseProblem(URL, path, &mu) diff --git a/config/config.go b/config/config.go index e2f4bef7..5d05aa4f 100644 --- a/config/config.go +++ b/config/config.go @@ -1,10 +1,10 @@ package config import ( + "bytes" "encoding/json" "io/ioutil" "os" - "bytes" "path/filepath" "github.com/fatih/color" diff --git a/cookiejar/jar.go b/cookiejar/jar.go deleted file mode 100644 index 62f440ea..00000000 --- a/cookiejar/jar.go +++ /dev/null @@ -1,555 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cookiejar implements an in-memory RFC 6265-compliant http.CookieJar. -package cookiejar - -import ( - "encoding/json" - "errors" - "fmt" - "net" - "net/http" - "net/url" - "sort" - "strings" - "sync" - "time" -) - -// PublicSuffixList provides the public suffix of a domain. For example: -// - the public suffix of "example.com" is "com", -// - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and -// - the public suffix of "bar.pvt.k12.ma.us" is "pvt.k12.ma.us". -// -// Implementations of PublicSuffixList must be safe for concurrent use by -// multiple goroutines. -// -// An implementation that always returns "" is valid and may be useful for -// testing but it is not secure: it means that the HTTP server for foo.com can -// set a cookie for bar.com. -// -// A public suffix list implementation is in the package -// golang.org/x/net/publicsuffix. -type PublicSuffixList interface { - // PublicSuffix returns the public suffix of domain. - // - // TODO: specify which of the caller and callee is responsible for IP - // addresses, for leading and trailing dots, for case sensitivity, and - // for IDN/Punycode. - PublicSuffix(domain string) string - - // String returns a description of the source of this public suffix - // list. The description will typically contain something like a time - // stamp or version number. - String() string -} - -// Options are the options for creating a new Jar. -type Options struct { - // PublicSuffixList is the public suffix list that determines whether - // an HTTP server can set a cookie for a domain. - // - // A nil value is valid and may be useful for testing but it is not - // secure: it means that the HTTP server for foo.co.uk can set a cookie - // for bar.co.uk. - PublicSuffixList PublicSuffixList -} - -// Jar implements the http.CookieJar interface from the net/http package. -type Jar struct { - psList PublicSuffixList - - // mu locks the remaining fields. - mu sync.Mutex - - // entries is a set of entries, keyed by their eTLD+1 and subkeyed by - // their name/domain/path. - entries map[string]map[string]entry - - // nextSeqNum is the next sequence number assigned to a new cookie - // created SetCookies. - nextSeqNum uint64 -} - -// New returns a new cookie jar. A nil *Options is equivalent to a zero -// Options. -func New(o *Options) (*Jar, error) { - jar := &Jar{ - entries: make(map[string]map[string]entry), - } - if o != nil { - jar.psList = o.PublicSuffixList - } - return jar, nil -} - -func deepCopy(value interface{}) interface{} { - if valueMap, ok := value.(map[string]interface{}); ok { - newMap := make(map[string]interface{}) - for k, v := range valueMap { - newMap[k] = deepCopy(v) - } - return newMap - } else if valueSlice, ok := value.([]interface{}); ok { - newSlice := make([]interface{}, len(valueSlice)) - for k, v := range valueSlice { - newSlice[k] = deepCopy(v) - } - return newSlice - } - return value -} - -// Copy the data to a new jar -func (j *Jar) Copy() *Jar { - j.mu.Lock() - entries := make(map[string]map[string]entry) - for k0, v0 := range j.entries { - e1 := make(map[string]entry) - for k1, v1 := range v0 { - e1[k1] = v1 - } - entries[k0] = e1 - } - j.mu.Unlock() - return &Jar{ - entries: entries, - } -} - -// MarshalJSON my impl -func (j *Jar) MarshalJSON() ([]byte, error) { - return json.Marshal(j.entries) -} - -// UnmarshalJSON my impl -func (j *Jar) UnmarshalJSON(data []byte) error { - entries := make(map[string]map[string]entry) - if err := json.Unmarshal(data, &entries); err != nil { - return err - } - j.mu.Lock() - j.entries = entries - j.mu.Unlock() - return nil -} - -// entry is the internal representation of a cookie. -// -// This struct type is not used outside of this package per se, but the exported -// fields are those of RFC 6265. -type entry struct { - Name string - Value string - Domain string - Path string - SameSite string - Secure bool - HttpOnly bool - Persistent bool - HostOnly bool - Expires time.Time - Creation time.Time - LastAccess time.Time - - // seqNum is a sequence number so that Cookies returns cookies in a - // deterministic order, even for cookies that have equal Path length and - // equal Creation time. This simplifies testing. - seqNum uint64 -} - -// id returns the domain;path;name triple of e as an id. -func (e *entry) id() string { - return fmt.Sprintf("%s;%s;%s", e.Domain, e.Path, e.Name) -} - -// shouldSend determines whether e's cookie qualifies to be included in a -// request to host/path. It is the caller's responsibility to check if the -// cookie is expired. -func (e *entry) shouldSend(https bool, host, path string) bool { - return e.domainMatch(host) && e.pathMatch(path) && (https || !e.Secure) -} - -// domainMatch implements "domain-match" of RFC 6265 section 5.1.3. -func (e *entry) domainMatch(host string) bool { - if e.Domain == host { - return true - } - return !e.HostOnly && hasDotSuffix(host, e.Domain) -} - -// pathMatch implements "path-match" according to RFC 6265 section 5.1.4. -func (e *entry) pathMatch(requestPath string) bool { - if requestPath == e.Path { - return true - } - if strings.HasPrefix(requestPath, e.Path) { - if e.Path[len(e.Path)-1] == '/' { - return true // The "/any/" matches "/any/path" case. - } else if requestPath[len(e.Path)] == '/' { - return true // The "/any" matches "/any/path" case. - } - } - return false -} - -// hasDotSuffix reports whether s ends in "."+suffix. -func hasDotSuffix(s, suffix string) bool { - return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix -} - -// Cookies implements the Cookies method of the http.CookieJar interface. -// -// It returns an empty slice if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie) { - return j.cookies(u, time.Now()) -} - -// cookies is like Cookies but takes the current time as a parameter. -func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) { - if u.Scheme != "http" && u.Scheme != "https" { - return cookies - } - host, err := canonicalHost(u.Host) - if err != nil { - return cookies - } - key := jarKey(host, j.psList) - - j.mu.Lock() - defer j.mu.Unlock() - - submap := j.entries[key] - if submap == nil { - return cookies - } - - https := u.Scheme == "https" - path := u.Path - if path == "" { - path = "/" - } - - modified := false - var selected []entry - for id, e := range submap { - if e.Persistent && !e.Expires.After(now) { - delete(submap, id) - modified = true - continue - } - if !e.shouldSend(https, host, path) { - continue - } - e.LastAccess = now - submap[id] = e - selected = append(selected, e) - modified = true - } - if modified { - if len(submap) == 0 { - delete(j.entries, key) - } else { - j.entries[key] = submap - } - } - - // sort according to RFC 6265 section 5.4 point 2: by longest - // path and then by earliest creation time. - sort.Slice(selected, func(i, j int) bool { - s := selected - if len(s[i].Path) != len(s[j].Path) { - return len(s[i].Path) > len(s[j].Path) - } - if !s[i].Creation.Equal(s[j].Creation) { - return s[i].Creation.Before(s[j].Creation) - } - return s[i].seqNum < s[j].seqNum - }) - for _, e := range selected { - cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value}) - } - - return cookies -} - -// SetCookies implements the SetCookies method of the http.CookieJar interface. -// -// It does nothing if the URL's scheme is not HTTP or HTTPS. -func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) { - j.setCookies(u, cookies, time.Now()) -} - -// setCookies is like SetCookies but takes the current time as parameter. -func (j *Jar) setCookies(u *url.URL, cookies []*http.Cookie, now time.Time) { - if len(cookies) == 0 { - return - } - if u.Scheme != "http" && u.Scheme != "https" { - return - } - host, err := canonicalHost(u.Host) - if err != nil { - return - } - key := jarKey(host, j.psList) - defPath := defaultPath(u.Path) - - j.mu.Lock() - defer j.mu.Unlock() - - submap := j.entries[key] - - modified := false - for _, cookie := range cookies { - e, remove, err := j.newEntry(cookie, now, defPath, host) - if err != nil { - continue - } - id := e.id() - if remove { - if submap != nil { - if _, ok := submap[id]; ok { - delete(submap, id) - modified = true - } - } - continue - } - if submap == nil { - submap = make(map[string]entry) - } - - if old, ok := submap[id]; ok { - e.Creation = old.Creation - e.seqNum = old.seqNum - } else { - e.Creation = now - e.seqNum = j.nextSeqNum - j.nextSeqNum++ - } - e.LastAccess = now - submap[id] = e - modified = true - } - - if modified { - if len(submap) == 0 { - delete(j.entries, key) - } else { - j.entries[key] = submap - } - } -} - -// canonicalHost strips port from host if present and returns the canonicalized -// host name. -func canonicalHost(host string) (string, error) { - var err error - host = strings.ToLower(host) - if hasPort(host) { - host, _, err = net.SplitHostPort(host) - if err != nil { - return "", err - } - } - if strings.HasSuffix(host, ".") { - // Strip trailing dot from fully qualified domain names. - host = host[:len(host)-1] - } - return toASCII(host) -} - -// hasPort reports whether host contains a port number. host may be a host -// name, an IPv4 or an IPv6 address. -func hasPort(host string) bool { - colons := strings.Count(host, ":") - if colons == 0 { - return false - } - if colons == 1 { - return true - } - return host[0] == '[' && strings.Contains(host, "]:") -} - -// jarKey returns the key to use for a jar. -func jarKey(host string, psl PublicSuffixList) string { - if isIP(host) { - return host - } - - var i int - if psl == nil { - i = strings.LastIndex(host, ".") - if i <= 0 { - return host - } - } else { - suffix := psl.PublicSuffix(host) - if suffix == host { - return host - } - i = len(host) - len(suffix) - if i <= 0 || host[i-1] != '.' { - // The provided public suffix list psl is broken. - // Storing cookies under host is a safe stopgap. - return host - } - // Only len(suffix) is used to determine the jar key from - // here on, so it is okay if psl.PublicSuffix("www.buggy.psl") - // returns "com" as the jar key is generated from host. - } - prevDot := strings.LastIndex(host[:i-1], ".") - return host[prevDot+1:] -} - -// isIP reports whether host is an IP address. -func isIP(host string) bool { - return net.ParseIP(host) != nil -} - -// defaultPath returns the directory part of an URL's path according to -// RFC 6265 section 5.1.4. -func defaultPath(path string) string { - if len(path) == 0 || path[0] != '/' { - return "/" // Path is empty or malformed. - } - - i := strings.LastIndex(path, "/") // Path starts with "/", so i != -1. - if i == 0 { - return "/" // Path has the form "/abc". - } - return path[:i] // Path is either of form "/abc/xyz" or "/abc/xyz/". -} - -// newEntry creates an entry from a http.Cookie c. now is the current time and -// is compared to c.Expires to determine deletion of c. defPath and host are the -// default-path and the canonical host name of the URL c was received from. -// -// remove records whether the jar should delete this cookie, as it has already -// expired with respect to now. In this case, e may be incomplete, but it will -// be valid to call e.id (which depends on e's Name, Domain and Path). -// -// A malformed c.Domain will result in an error. -func (j *Jar) newEntry(c *http.Cookie, now time.Time, defPath, host string) (e entry, remove bool, err error) { - e.Name = c.Name - - if c.Path == "" || c.Path[0] != '/' { - e.Path = defPath - } else { - e.Path = c.Path - } - - e.Domain, e.HostOnly, err = j.domainAndType(host, c.Domain) - if err != nil { - return e, false, err - } - - // MaxAge takes precedence over Expires. - if c.MaxAge < 0 { - return e, true, nil - } else if c.MaxAge > 0 { - e.Expires = now.Add(time.Duration(c.MaxAge) * time.Second) - e.Persistent = true - } else { - if c.Expires.IsZero() { - e.Expires = endOfTime - e.Persistent = false - } else { - if !c.Expires.After(now) { - return e, true, nil - } - e.Expires = c.Expires - e.Persistent = true - } - } - - e.Value = c.Value - e.Secure = c.Secure - e.HttpOnly = c.HttpOnly - - switch c.SameSite { - case http.SameSiteDefaultMode: - e.SameSite = "SameSite" - case http.SameSiteStrictMode: - e.SameSite = "SameSite=Strict" - case http.SameSiteLaxMode: - e.SameSite = "SameSite=Lax" - } - - return e, false, nil -} - -var ( - errIllegalDomain = errors.New("cookiejar: illegal cookie domain attribute") - errMalformedDomain = errors.New("cookiejar: malformed cookie domain attribute") - errNoHostname = errors.New("cookiejar: no host name available (IP only)") -) - -// endOfTime is the time when session (non-persistent) cookies expire. -// This instant is representable in most date/time formats (not just -// Go's time.Time) and should be far enough in the future. -var endOfTime = time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC) - -// domainAndType determines the cookie's domain and hostOnly attribute. -func (j *Jar) domainAndType(host, domain string) (string, bool, error) { - if domain == "" { - // No domain attribute in the SetCookie header indicates a - // host cookie. - return host, true, nil - } - - if isIP(host) { - // According to RFC 6265 domain-matching includes not being - // an IP address. - // TODO: This might be relaxed as in common browsers. - return "", false, errNoHostname - } - - // From here on: If the cookie is valid, it is a domain cookie (with - // the one exception of a public suffix below). - // See RFC 6265 section 5.2.3. - if domain[0] == '.' { - domain = domain[1:] - } - - if len(domain) == 0 || domain[0] == '.' { - // Received either "Domain=." or "Domain=..some.thing", - // both are illegal. - return "", false, errMalformedDomain - } - domain = strings.ToLower(domain) - - if domain[len(domain)-1] == '.' { - // We received stuff like "Domain=www.example.com.". - // Browsers do handle such stuff (actually differently) but - // RFC 6265 seems to be clear here (e.g. section 4.1.2.3) in - // requiring a reject. 4.1.2.3 is not normative, but - // "Domain Matching" (5.1.3) and "Canonicalized Host Names" - // (5.1.2) are. - return "", false, errMalformedDomain - } - - // See RFC 6265 section 5.3 #5. - if j.psList != nil { - if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) { - if host == domain { - // This is the one exception in which a cookie - // with a domain attribute is a host cookie. - return host, true, nil - } - return "", false, errIllegalDomain - } - } - - // The domain must domain-match host: www.mycompany.com cannot - // set cookies for .ourcompetitors.com. - if host != domain && !hasDotSuffix(host, domain) { - return "", false, errIllegalDomain - } - - return domain, false, nil -} diff --git a/cookiejar/punycode.go b/cookiejar/punycode.go deleted file mode 100644 index a9cc666e..00000000 --- a/cookiejar/punycode.go +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cookiejar - -// This file implements the Punycode algorithm from RFC 3492. - -import ( - "fmt" - "strings" - "unicode/utf8" -) - -// These parameter values are specified in section 5. -// -// All computation is done with int32s, so that overflow behavior is identical -// regardless of whether int is 32-bit or 64-bit. -const ( - base int32 = 36 - damp int32 = 700 - initialBias int32 = 72 - initialN int32 = 128 - skew int32 = 38 - tmax int32 = 26 - tmin int32 = 1 -) - -// encode encodes a string as specified in section 6.3 and prepends prefix to -// the result. -// -// The "while h < length(input)" line in the specification becomes "for -// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes. -func encode(prefix, s string) (string, error) { - output := make([]byte, len(prefix), len(prefix)+1+2*len(s)) - copy(output, prefix) - delta, n, bias := int32(0), initialN, initialBias - b, remaining := int32(0), int32(0) - for _, r := range s { - if r < utf8.RuneSelf { - b++ - output = append(output, byte(r)) - } else { - remaining++ - } - } - h := b - if b > 0 { - output = append(output, '-') - } - for remaining != 0 { - m := int32(0x7fffffff) - for _, r := range s { - if m > r && r >= n { - m = r - } - } - delta += (m - n) * (h + 1) - if delta < 0 { - return "", fmt.Errorf("cookiejar: invalid label %q", s) - } - n = m - for _, r := range s { - if r < n { - delta++ - if delta < 0 { - return "", fmt.Errorf("cookiejar: invalid label %q", s) - } - continue - } - if r > n { - continue - } - q := delta - for k := base; ; k += base { - t := k - bias - if t < tmin { - t = tmin - } else if t > tmax { - t = tmax - } - if q < t { - break - } - output = append(output, encodeDigit(t+(q-t)%(base-t))) - q = (q - t) / (base - t) - } - output = append(output, encodeDigit(q)) - bias = adapt(delta, h+1, h == b) - delta = 0 - h++ - remaining-- - } - delta++ - n++ - } - return string(output), nil -} - -func encodeDigit(digit int32) byte { - switch { - case 0 <= digit && digit < 26: - return byte(digit + 'a') - case 26 <= digit && digit < 36: - return byte(digit + ('0' - 26)) - } - panic("cookiejar: internal error in punycode encoding") -} - -// adapt is the bias adaptation function specified in section 6.1. -func adapt(delta, numPoints int32, firstTime bool) int32 { - if firstTime { - delta /= damp - } else { - delta /= 2 - } - delta += delta / numPoints - k := int32(0) - for delta > ((base-tmin)*tmax)/2 { - delta /= base - tmin - k += base - } - return k + (base-tmin+1)*delta/(delta+skew) -} - -// Strictly speaking, the remaining code below deals with IDNA (RFC 5890 and -// friends) and not Punycode (RFC 3492) per se. - -// acePrefix is the ASCII Compatible Encoding prefix. -const acePrefix = "xn--" - -// toASCII converts a domain or domain label to its ASCII form. For example, -// toASCII("bücher.example.com") is "xn--bcher-kva.example.com", and -// toASCII("golang") is "golang". -func toASCII(s string) (string, error) { - if ascii(s) { - return s, nil - } - labels := strings.Split(s, ".") - for i, label := range labels { - if !ascii(label) { - a, err := encode(acePrefix, label) - if err != nil { - return "", err - } - labels[i] = a - } - } - return strings.Join(labels, "."), nil -} - -func ascii(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] >= utf8.RuneSelf { - return false - } - } - return true -} diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..8196bf7c --- /dev/null +++ b/go.mod @@ -0,0 +1,32 @@ +module github.com/xalanq/cf-tool + +go 1.21.2 + +require ( + github.com/PuerkitoBio/goquery v1.8.1 + github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 + github.com/fatih/color v1.16.0 + github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 + github.com/mitchellh/go-homedir v1.1.0 + github.com/olekukonko/tablewriter v0.0.5 + github.com/sergi/go-diff v1.3.1 + github.com/shirou/gopsutil v3.21.11+incompatible + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 + golang.org/x/crypto v0.18.0 +) + +require ( + github.com/andybalholm/cascadia v1.3.1 // indirect + github.com/draychev/go-toolbox v0.0.0-20231003060312-b5c11a822944 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/rs/zerolog v1.29.1 // indirect + github.com/tklauser/go-sysconf v0.3.13 // indirect + github.com/tklauser/numcpus v0.7.0 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..5052d72d --- /dev/null +++ b/go.sum @@ -0,0 +1,104 @@ +github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= +github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= +github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= +github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/draychev/go-toolbox v0.0.0-20231003060312-b5c11a822944 h1:yyCoZlczNxoNLlx/3BB69I0QjyxWyAK9zJi+2DpDrfY= +github.com/draychev/go-toolbox v0.0.0-20231003060312-b5c11a822944/go.mod h1:hwGEl5n94est1h1mEOPJOBNzPXzL4iAivcQKce5VaB4= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213 h1:qGQQKEcAR99REcMpsXCp3lJ03zYT1PkRd3kQGPn9GVg= +github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= +github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= +github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= +github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= +github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/vendor/github.com/PuerkitoBio/goquery/.gitattributes b/vendor/github.com/PuerkitoBio/goquery/.gitattributes deleted file mode 100644 index 0cc26ec0..00000000 --- a/vendor/github.com/PuerkitoBio/goquery/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -testdata/* linguist-vendored diff --git a/vendor/github.com/PuerkitoBio/goquery/.gitignore b/vendor/github.com/PuerkitoBio/goquery/.gitignore deleted file mode 100644 index 970381cd..00000000 --- a/vendor/github.com/PuerkitoBio/goquery/.gitignore +++ /dev/null @@ -1,16 +0,0 @@ -# editor temporary files -*.sublime-* -.DS_Store -*.swp -#*.*# -tags - -# direnv config -.env* - -# test binaries -*.test - -# coverage and profilte outputs -*.out - diff --git a/vendor/github.com/PuerkitoBio/goquery/.travis.yml b/vendor/github.com/PuerkitoBio/goquery/.travis.yml deleted file mode 100644 index cc1402d5..00000000 --- a/vendor/github.com/PuerkitoBio/goquery/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: go - -go: - - 1.1 - - 1.2.x - - 1.3.x - - 1.4.x - - 1.5.x - - 1.6.x - - 1.7.x - - 1.8.x - - 1.9.x - - "1.10.x" - - 1.11.x - - tip - diff --git a/vendor/github.com/PuerkitoBio/goquery/LICENSE b/vendor/github.com/PuerkitoBio/goquery/LICENSE deleted file mode 100644 index f743d372..00000000 --- a/vendor/github.com/PuerkitoBio/goquery/LICENSE +++ /dev/null @@ -1,12 +0,0 @@ -Copyright (c) 2012-2016, Martin Angers & Contributors -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. - -* Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -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 HOLDER 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/PuerkitoBio/goquery/README.md b/vendor/github.com/PuerkitoBio/goquery/README.md deleted file mode 100644 index 84f9af39..00000000 --- a/vendor/github.com/PuerkitoBio/goquery/README.md +++ /dev/null @@ -1,179 +0,0 @@ -# goquery - a little like that j-thing, only in Go -[](http://travis-ci.org/PuerkitoBio/goquery) [](http://godoc.org/github.com/PuerkitoBio/goquery) [](https://sourcegraph.com/github.com/PuerkitoBio/goquery?badge) - -goquery brings a syntax and a set of features similar to [jQuery][] to the [Go language][go]. It is based on Go's [net/html package][html] and the CSS Selector library [cascadia][]. Since the net/html parser returns nodes, and not a full-featured DOM tree, jQuery's stateful manipulation functions (like height(), css(), detach()) have been left off. - -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. See the [wiki][] for various options to do this. - -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()][index]...). - -## Table of Contents - -* [Installation](#installation) -* [Changelog](#changelog) -* [API](#api) -* [Examples](#examples) -* [Related Projects](#related-projects) -* [Support](#support) -* [License](#license) - -## Installation - -Please note that because of the net/html dependency, goquery requires Go1.1+. - - $ go get github.com/PuerkitoBio/goquery - -(optional) To run unit tests: - - $ cd $GOPATH/src/github.com/PuerkitoBio/goquery - $ go test - -(optional) To run benchmarks (warning: it runs for a few minutes): - - $ cd $GOPATH/src/github.com/PuerkitoBio/goquery - $ go test -bench=".*" - -## Changelog - -**Note that goquery's API is now stable, and will not break.** - -* **2018-11-15 (v1.5.0)** : Go module support (thanks @Zaba505). -* **2018-06-07 (v1.4.1)** : Add `NewDocumentFromReader` examples. -* **2018-03-24 (v1.4.0)** : Deprecate `NewDocument(url)` and `NewDocumentFromResponse(response)`. -* **2018-01-28 (v1.3.0)** : Add `ToEnd` constant to `Slice` until the end of the selection (thanks to @davidjwilkins for raising the issue). -* **2018-01-11 (v1.2.0)** : Add `AddBack*` and deprecate `AndSelf` (thanks to @davidjwilkins). -* **2017-02-12 (v1.1.0)** : Add `SetHtml` and `SetText` (thanks to @glebtv). -* **2016-12-29 (v1.0.2)** : Optimize allocations for `Selection.Text` (thanks to @radovskyb). -* **2016-08-28 (v1.0.1)** : Optimize performance for large documents. -* **2016-07-27 (v1.0.0)** : Tag version 1.0.0. -* **2016-06-15** : Invalid selector strings internally compile to a `Matcher` implementation that never matches any node (instead of a panic). So for example, `doc.Find("~")` returns an empty `*Selection` object. -* **2016-02-02** : Add `NodeName` utility function similar to the DOM's `nodeName` property. It returns the tag name of the first element in a selection, and other relevant values of non-element nodes (see godoc for details). Add `OuterHtml` utility function similar to the DOM's `outerHTML` property (named `OuterHtml` in small caps for consistency with the existing `Html` method on the `Selection`). -* **2015-04-20** : Add `AttrOr` helper method to return the attribute's value or a default value if absent. Thanks to [piotrkowalczuk][piotr]. -* **2015-02-04** : Add more manipulation functions - Prepend* - thanks again to [Andrew Stone][thatguystone]. -* **2014-11-28** : Add more manipulation functions - ReplaceWith*, Wrap* and Unwrap - thanks again to [Andrew Stone][thatguystone]. -* **2014-11-07** : Add manipulation functions (thanks to [Andrew Stone][thatguystone]) and `*Matcher` functions, that receive compiled cascadia selectors instead of selector strings, thus avoiding potential panics thrown by goquery via `cascadia.MustCompile` calls. This results in better performance (selectors can be compiled once and reused) and more idiomatic error handling (you can handle cascadia's compilation errors, instead of recovering from panics, which had been bugging me for a long time). Note that the actual type expected is a `Matcher` interface, that `cascadia.Selector` implements. Other matcher implementations could be used. -* **2014-11-06** : Change import paths of net/html to golang.org/x/net/html (see https://groups.google.com/forum/#!topic/golang-nuts/eD8dh3T9yyA). Make sure to update your code to use the new import path too when you call goquery with `html.Node`s. -* **v0.3.2** : Add `NewDocumentFromReader()` (thanks jweir) which allows creating a goquery document from an io.Reader. -* **v0.3.1** : Add `NewDocumentFromResponse()` (thanks assassingj) which allows creating a goquery document from an http response. -* **v0.3.0** : Add `EachWithBreak()` which allows to break out of an `Each()` loop by returning false. This function was added instead of changing the existing `Each()` to avoid breaking compatibility. -* **v0.2.1** : Make go-getable, now that [go.net/html is Go1.0-compatible][gonet] (thanks to @matrixik for pointing this out). -* **v0.2.0** : Add support for negative indices in Slice(). **BREAKING CHANGE** `Document.Root` is removed, `Document` is now a `Selection` itself (a selection of one, the root element, just like `Document.Root` was before). Add jQuery's Closest() method. -* **v0.1.1** : Add benchmarks to use as baseline for refactorings, refactor Next...() and Prev...() methods to use the new html package's linked list features (Next/PrevSibling, FirstChild). Good performance boost (40+% in some cases). -* **v0.1.0** : Initial release. - -## API - -goquery exposes two structs, `Document` and `Selection`, and the `Matcher` interface. Unlike jQuery, which is loaded as part of a DOM document, and thus acts on its containing document, goquery doesn't know which HTML document to act upon. So it needs to be told, and that's what the `Document` type is for. It holds the root document node as the initial Selection value to manipulate. - -jQuery often has many variants for the same function (no argument, a selector string argument, a jQuery object argument, a DOM element argument, ...). Instead of exposing the same features in goquery as a single method with variadic empty interface arguments, statically-typed signatures are used following this naming convention: - -* When the jQuery equivalent can be called with no argument, it has the same name as jQuery for the no argument signature (e.g.: `Prev()`), and the version with a selector string argument is called `XxxFiltered()` (e.g.: `PrevFiltered()`) -* When the jQuery equivalent **requires** one argument, the same name as jQuery is used for the selector string version (e.g.: `Is()`) -* The signatures accepting a jQuery object as argument are defined in goquery as `XxxSelection()` and take a `*Selection` object as argument (e.g.: `FilterSelection()`) -* The signatures accepting a DOM element as argument in jQuery are defined in goquery as `XxxNodes()` and take a variadic argument of type `*html.Node` (e.g.: `FilterNodes()`) -* The signatures accepting a function as argument in jQuery are defined in goquery as `XxxFunction()` and take a function as argument (e.g.: `FilterFunction()`) -* The goquery methods that can be called with a selector string have a corresponding version that take a `Matcher` interface and are defined as `XxxMatcher()` (e.g.: `IsMatcher()`) - -Utility functions that are not in jQuery but are useful in Go are implemented as functions (that take a `*Selection` as parameter), to avoid a potential naming clash on the `*Selection`'s methods (reserved for jQuery-equivalent behaviour). - -The complete [godoc reference documentation can be found here][doc]. - -Please note that Cascadia's selectors do not necessarily match all supported selectors of jQuery (Sizzle). See the [cascadia project][cascadia] for details. Invalid selector strings compile to a `Matcher` that fails to match any node. Behaviour of the various functions that take a selector string as argument follows from that fact, e.g. (where `~` is an invalid selector string): - -* `Find("~")` returns an empty selection because the selector string doesn't match anything. -* `Add("~")` returns a new selection that holds the same nodes as the original selection, because it didn't add any node (selector string didn't match anything). -* `ParentsFiltered("~")` returns an empty selection because the selector string doesn't match anything. -* `ParentsUntil("~")` returns all parents of the selection because the selector string didn't match any element to stop before the top element. - -## Examples - -See some tips and tricks in the [wiki][]. - -Adapted from example_test.go: - -```Go -package main - -import ( - "fmt" - "log" - "net/http" - - "github.com/PuerkitoBio/goquery" -) - -func ExampleScrape() { - // Request the HTML page. - res, err := http.Get("http://metalsucks.net") - if err != nil { - log.Fatal(err) - } - defer res.Body.Close() - if res.StatusCode != 200 { - log.Fatalf("status code error: %d %s", res.StatusCode, res.Status) - } - - // Load the HTML document - doc, err := goquery.NewDocumentFromReader(res.Body) - if err != nil { - log.Fatal(err) - } - - // Find the review items - doc.Find(".sidebar-reviews article .content-block").Each(func(i int, s *goquery.Selection) { - // For each item found, get the band and title - band := s.Find("a").Text() - title := s.Find("i").Text() - fmt.Printf("Review %d: %s - %s\n", i, band, title) - }) -} - -func main() { - ExampleScrape() -} -``` - -## Related Projects - -- [Goq][goq], an HTML deserialization and scraping library based on goquery and struct tags. -- [andybalholm/cascadia][cascadia], the CSS selector library used by goquery. -- [suntong/cascadia][cascadiacli], a command-line interface to the cascadia CSS selector library, useful to test selectors. -- [asciimoo/colly](https://github.com/asciimoo/colly), a lightning fast and elegant Scraping Framework -- [gnulnx/goperf](https://github.com/gnulnx/goperf), a website performance test tool that also fetches static assets. -- [MontFerret/ferret](https://github.com/MontFerret/ferret), declarative web scraping. - -## Support - -There are a number of ways you can support the project: - -* Use it, star it, build something with it, spread the word! - - If you do build something open-source or otherwise publicly-visible, let me know so I can add it to the [Related Projects](#related-projects) section! -* Raise issues to improve the project (note: doc typos and clarifications are issues too!) - - Please search existing issues before opening a new one - it may have already been adressed. -* Pull requests: please discuss new code in an issue first, unless the fix is really trivial. - - Make sure new code is tested. - - Be mindful of existing code - PRs that break existing code have a high probability of being declined, unless it fixes a serious issue. - -If you desperately want to send money my way, I have a BuyMeACoffee.com page: - -
-
-## License
-
-The [BSD 3-Clause license][bsd], the same as the [Go language][golic]. Cascadia's license is [here][caslic].
-
-[jquery]: http://jquery.com/
-[go]: http://golang.org/
-[cascadia]: https://github.com/andybalholm/cascadia
-[cascadiacli]: https://github.com/suntong/cascadia
-[bsd]: http://opensource.org/licenses/BSD-3-Clause
-[golic]: http://golang.org/LICENSE
-[caslic]: https://github.com/andybalholm/cascadia/blob/master/LICENSE
-[doc]: http://godoc.org/github.com/PuerkitoBio/goquery
-[index]: http://api.jquery.com/index/
-[gonet]: https://github.com/golang/net/
-[html]: http://godoc.org/golang.org/x/net/html
-[wiki]: https://github.com/PuerkitoBio/goquery/wiki/Tips-and-tricks
-[thatguystone]: https://github.com/thatguystone
-[piotr]: https://github.com/piotrkowalczuk
-[goq]: https://github.com/andrewstuart/goq
diff --git a/vendor/github.com/PuerkitoBio/goquery/array.go b/vendor/github.com/PuerkitoBio/goquery/array.go
deleted file mode 100644
index 1b1f6cbe..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/array.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package goquery
-
-import (
- "golang.org/x/net/html"
-)
-
-const (
- maxUint = ^uint(0)
- maxInt = int(maxUint >> 1)
-
- // ToEnd is a special index value that can be used as end index in a call
- // to Slice so that all elements are selected until the end of the Selection.
- // It is equivalent to passing (*Selection).Length().
- ToEnd = maxInt
-)
-
-// 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 (s *Selection) First() *Selection {
- return s.Eq(0)
-}
-
-// 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 (s *Selection) Last() *Selection {
- return s.Eq(-1)
-}
-
-// 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 (s *Selection) Eq(index int) *Selection {
- if index < 0 {
- index += len(s.Nodes)
- }
-
- if index >= len(s.Nodes) || index < 0 {
- return newEmptySelection(s.document)
- }
-
- return s.Slice(index, index+1)
-}
-
-// Slice reduces the set of matched elements to a subset specified by a range
-// of indices. The start index is 0-based and indicates the index of the first
-// element to select. The end index is 0-based and indicates the index at which
-// the elements stop being selected (the end index is not selected).
-//
-// The indices may be negative, in which case they represent an offset from the
-// end of the selection.
-//
-// The special value ToEnd may be specified as end index, in which case all elements
-// until the end are selected. This works both for a positive and negative start
-// index.
-func (s *Selection) Slice(start, end int) *Selection {
- if start < 0 {
- start += len(s.Nodes)
- }
- if end == ToEnd {
- end = len(s.Nodes)
- } else if end < 0 {
- end += len(s.Nodes)
- }
- 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
-// on the Selection object.
-func (s *Selection) Get(index int) *html.Node {
- if index < 0 {
- index += len(s.Nodes) // Negative index gets from the end
- }
- return s.Nodes[index]
-}
-
-// Index returns the position of the first element within the Selection object
-// relative to its sibling elements.
-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
-// Selection object relative to the elements matched by the selector, or -1 if
-// not found.
-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
-}
-
-// IndexMatcher returns the position of the first element within the
-// Selection object relative to the elements matched by the matcher, or -1 if
-// not found.
-func (s *Selection) IndexMatcher(m Matcher) int {
- if len(s.Nodes) > 0 {
- sel := s.document.FindMatcher(m)
- return indexInSlice(sel.Nodes, s.Nodes[0])
- }
- return -1
-}
-
-// IndexOfNode returns the position of the specified node within the Selection
-// object, or -1 if not found.
-func (s *Selection) IndexOfNode(node *html.Node) int {
- return indexInSlice(s.Nodes, node)
-}
-
-// IndexOfSelection returns the position of the first node in the specified
-// Selection object within this Selection object, or -1 if not found.
-func (s *Selection) IndexOfSelection(sel *Selection) int {
- if sel != nil && len(sel.Nodes) > 0 {
- return indexInSlice(s.Nodes, sel.Nodes[0])
- }
- return -1
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/doc.go b/vendor/github.com/PuerkitoBio/goquery/doc.go
deleted file mode 100644
index 71146a78..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/doc.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright (c) 2012-2016, Martin Angers & Contributors
-// 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.
-// * Neither the name of the author nor the names of its contributors may be used to
-// endorse or promote products derived from this software without specific prior written permission.
-//
-// 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 HOLDER 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.
-
-/*
-Package goquery implements features similar to jQuery, including the chainable
-syntax, to manipulate and query an HTML document.
-
-It 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 nodes, and not a full-featured DOM
-tree, jQuery's stateful manipulation functions (like height(), css(), detach())
-have been left off.
-
-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.
-See the repository's wiki for various options on how to do this.
-
-Syntax-wise, it is as close as possible to jQuery, with the same method names when
-possible, and that warm and fuzzy chainable interface. jQuery being the
-ultra-popular library that it is, 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
-
-Please note that because of the net/html dependency, goquery requires Go1.1+.
-
-The various methods are split into files based on the category of behavior.
-The three dots (...) indicate that various "overloads" are available.
-
-* array.go : array-like positional manipulation of the selection.
- - Eq()
- - First()
- - Get()
- - Index...()
- - Last()
- - Slice()
-
-* expand.go : methods that expand or augment the selection's set.
- - Add...()
- - AndSelf()
- - Union(), which is an alias for AddSelection()
-
-* filter.go : filtering methods, that reduce the selection's set.
- - End()
- - Filter...()
- - Has...()
- - Intersection(), which is an alias of FilterSelection()
- - Not...()
-
-* iteration.go : methods to loop over the selection's nodes.
- - Each()
- - EachWithBreak()
- - Map()
-
-* manipulation.go : methods for modifying the document
- - After...()
- - Append...()
- - Before...()
- - Clone()
- - Empty()
- - Prepend...()
- - Remove...()
- - ReplaceWith...()
- - Unwrap()
- - Wrap...()
- - WrapAll...()
- - WrapInner...()
-
-* property.go : methods that inspect and get the node's properties values.
- - Attr*(), RemoveAttr(), SetAttr()
- - AddClass(), HasClass(), RemoveClass(), ToggleClass()
- - Html()
- - Length()
- - Size(), which is an alias for Length()
- - Text()
-
-* query.go : methods that query, or reflect, a node's identity.
- - Contains()
- - Is...()
-
-* traversal.go : methods to traverse the HTML document tree.
- - Children...()
- - Contents()
- - Find...()
- - Next...()
- - Parent[s]...()
- - Prev...()
- - Siblings...()
-
-* type.go : definition of the types exposed by goquery.
- - Document
- - Selection
- - Matcher
-
-* utilities.go : definition of helper functions (and not methods on a *Selection)
-that are not part of jQuery, but are useful to goquery.
- - NodeName
- - OuterHtml
-*/
-package goquery
diff --git a/vendor/github.com/PuerkitoBio/goquery/expand.go b/vendor/github.com/PuerkitoBio/goquery/expand.go
deleted file mode 100644
index 7caade53..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/expand.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package goquery
-
-import "golang.org/x/net/html"
-
-// 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 (s *Selection) Add(selector string) *Selection {
- return s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, compileMatcher(selector))...)
-}
-
-// AddMatcher adds the matcher's matching nodes to those in the current
-// selection and returns a new Selection object.
-// The matcher is run in the context of the document of the current
-// Selection object.
-func (s *Selection) AddMatcher(m Matcher) *Selection {
- return s.AddNodes(findWithMatcher([]*html.Node{s.document.rootNode}, m)...)
-}
-
-// AddSelection adds the specified Selection object's nodes to those in the
-// current selection and returns a new Selection object.
-func (s *Selection) AddSelection(sel *Selection) *Selection {
- if sel == nil {
- return s.AddNodes()
- }
- return s.AddNodes(sel.Nodes...)
-}
-
-// 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
-// current selection and returns a new Selection object.
-func (s *Selection) AddNodes(nodes ...*html.Node) *Selection {
- return pushStack(s, appendWithoutDuplicates(s.Nodes, nodes, nil))
-}
-
-// 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.
-// Deprecated: This function has been deprecated and is now an alias for AddBack().
-func (s *Selection) AndSelf() *Selection {
- return s.AddBack()
-}
-
-// AddBack 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 (s *Selection) AddBack() *Selection {
- return s.AddSelection(s.prevSel)
-}
-
-// AddBackFiltered reduces the previous set of elements on the stack to those that
-// match the selector string, and adds them to the current set.
-// It returns a new Selection object containing the current Selection combined
-// with the filtered previous one
-func (s *Selection) AddBackFiltered(selector string) *Selection {
- return s.AddSelection(s.prevSel.Filter(selector))
-}
-
-// AddBackMatcher reduces the previous set of elements on the stack to those that match
-// the mateher, and adds them to the curernt set.
-// It returns a new Selection object containing the current Selection combined
-// with the filtered previous one
-func (s *Selection) AddBackMatcher(m Matcher) *Selection {
- return s.AddSelection(s.prevSel.FilterMatcher(m))
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/filter.go b/vendor/github.com/PuerkitoBio/goquery/filter.go
deleted file mode 100644
index 9138ffb3..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/filter.go
+++ /dev/null
@@ -1,163 +0,0 @@
-package goquery
-
-import "golang.org/x/net/html"
-
-// 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 (s *Selection) Filter(selector string) *Selection {
- return s.FilterMatcher(compileMatcher(selector))
-}
-
-// FilterMatcher reduces the set of matched elements to those that match
-// the given matcher. It returns a new Selection object for this subset
-// of matching elements.
-func (s *Selection) FilterMatcher(m Matcher) *Selection {
- return pushStack(s, winnow(s, m, true))
-}
-
-// Not removes elements from the Selection that match the selector string.
-// It returns a new Selection object with the matching elements removed.
-func (s *Selection) Not(selector string) *Selection {
- return s.NotMatcher(compileMatcher(selector))
-}
-
-// NotMatcher removes elements from the Selection that match the given matcher.
-// It returns a new Selection object with the matching elements removed.
-func (s *Selection) NotMatcher(m Matcher) *Selection {
- return pushStack(s, winnow(s, m, false))
-}
-
-// 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 (s *Selection) FilterFunction(f func(int, *Selection) bool) *Selection {
- return pushStack(s, winnowFunction(s, f, true))
-}
-
-// NotFunction removes elements from the Selection that pass the function's test.
-// It returns a new Selection object with the matching elements removed.
-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.
-// It returns a new Selection object for this subset of elements.
-func (s *Selection) FilterNodes(nodes ...*html.Node) *Selection {
- return pushStack(s, winnowNodes(s, nodes, true))
-}
-
-// NotNodes removes elements from the Selection that match the specified nodes.
-// It returns a new Selection object with the matching elements removed.
-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
-// node in the specified Selection object.
-// It returns a new Selection object for this subset of elements.
-func (s *Selection) FilterSelection(sel *Selection) *Selection {
- if sel == nil {
- return pushStack(s, winnowNodes(s, nil, true))
- }
- return pushStack(s, winnowNodes(s, sel.Nodes, true))
-}
-
-// NotSelection 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 (s *Selection) NotSelection(sel *Selection) *Selection {
- if sel == nil {
- return pushStack(s, winnowNodes(s, nil, false))
- }
- return pushStack(s, winnowNodes(s, sel.Nodes, false))
-}
-
-// 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
-// that matches the selector.
-// It returns a new Selection object with the matching elements.
-func (s *Selection) Has(selector string) *Selection {
- return s.HasSelection(s.document.Find(selector))
-}
-
-// HasMatcher reduces the set of matched elements to those that have a descendant
-// that matches the matcher.
-// It returns a new Selection object with the matching elements.
-func (s *Selection) HasMatcher(m Matcher) *Selection {
- return s.HasSelection(s.document.FindMatcher(m))
-}
-
-// 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 (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 sel.Contains(n) {
- return true
- }
- }
- return false
- })
-}
-
-// 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 (s *Selection) HasSelection(sel *Selection) *Selection {
- if sel == nil {
- return s.HasNodes()
- }
- return s.HasNodes(sel.Nodes...)
-}
-
-// End ends the most recent filtering operation in the current chain and
-// returns the set of matched elements to its previous state.
-func (s *Selection) End() *Selection {
- if s.prevSel != nil {
- return s.prevSel
- }
- return newEmptySelection(s.document)
-}
-
-// Filter based on the matcher, and the indicator to keep (Filter) or
-// to get rid of (Not) the matching elements.
-func winnow(sel *Selection, m Matcher, keep bool) []*html.Node {
- // Optimize if keep is requested
- if keep {
- return m.Filter(sel.Nodes)
- }
- // Use grep
- return grep(sel, func(i int, s *Selection) bool {
- return !m.Match(s.Get(0))
- })
-}
-
-// Filter based on an array of nodes, and the indicator to keep (Filter) or
-// to get rid of (Not) the matching elements.
-func winnowNodes(sel *Selection, nodes []*html.Node, keep bool) []*html.Node {
- if len(nodes)+len(sel.Nodes) < minNodesForSet {
- return grep(sel, func(i int, s *Selection) bool {
- return isInSlice(nodes, s.Get(0)) == keep
- })
- }
-
- set := make(map[*html.Node]bool)
- for _, n := range nodes {
- set[n] = true
- }
- return grep(sel, func(i int, s *Selection) bool {
- return set[s.Get(0)] == keep
- })
-}
-
-// Filter based on a function test, and the indicator to keep (Filter) or
-// to get rid of (Not) the matching elements.
-func winnowFunction(sel *Selection, f func(int, *Selection) bool, keep bool) []*html.Node {
- return grep(sel, func(i int, s *Selection) bool {
- return f(i, s) == keep
- })
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/go.mod b/vendor/github.com/PuerkitoBio/goquery/go.mod
deleted file mode 100644
index 2fa1332a..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/go.mod
+++ /dev/null
@@ -1,6 +0,0 @@
-module github.com/PuerkitoBio/goquery
-
-require (
- github.com/andybalholm/cascadia v1.0.0
- golang.org/x/net v0.0.0-20181114220301-adae6a3d119a
-)
diff --git a/vendor/github.com/PuerkitoBio/goquery/go.sum b/vendor/github.com/PuerkitoBio/goquery/go.sum
deleted file mode 100644
index 11c57575..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/go.sum
+++ /dev/null
@@ -1,5 +0,0 @@
-github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
-github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
-golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
diff --git a/vendor/github.com/PuerkitoBio/goquery/iteration.go b/vendor/github.com/PuerkitoBio/goquery/iteration.go
deleted file mode 100644
index e246f2e0..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/iteration.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package goquery
-
-// Each iterates over a Selection object, executing a function for each
-// matched element. It returns the current Selection object. The function
-// f is called for each element in the selection with the index of the
-// element in that selection starting at 0, and a *Selection that contains
-// only that element.
-func (s *Selection) Each(f func(int, *Selection)) *Selection {
- for i, n := range s.Nodes {
- f(i, newSingleSelection(n, s.document))
- }
- 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
-// current Selection object.
-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 s
-}
-
-// Map passes each element in the current matched set through a function,
-// producing a slice of string holding the returned values. The function
-// f is called for each element in the selection with the index of the
-// element in that selection starting at 0, and a *Selection that contains
-// only that element.
-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
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/manipulation.go b/vendor/github.com/PuerkitoBio/goquery/manipulation.go
deleted file mode 100644
index 34eb7570..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/manipulation.go
+++ /dev/null
@@ -1,574 +0,0 @@
-package goquery
-
-import (
- "strings"
-
- "golang.org/x/net/html"
-)
-
-// After applies the selector from the root document and inserts the matched elements
-// after the elements in the set of matched elements.
-//
-// If one of the matched elements in the selection is not currently in the
-// document, it's impossible to insert nodes after it, so it will be ignored.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) After(selector string) *Selection {
- return s.AfterMatcher(compileMatcher(selector))
-}
-
-// AfterMatcher applies the matcher from the root document and inserts the matched elements
-// after the elements in the set of matched elements.
-//
-// If one of the matched elements in the selection is not currently in the
-// document, it's impossible to insert nodes after it, so it will be ignored.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) AfterMatcher(m Matcher) *Selection {
- return s.AfterNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// AfterSelection inserts the elements in the selection after each element in the set of matched
-// elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) AfterSelection(sel *Selection) *Selection {
- return s.AfterNodes(sel.Nodes...)
-}
-
-// AfterHtml parses the html and inserts it after the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) AfterHtml(html string) *Selection {
- return s.AfterNodes(parseHtml(html)...)
-}
-
-// AfterNodes inserts the nodes after each element in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) AfterNodes(ns ...*html.Node) *Selection {
- return s.manipulateNodes(ns, true, func(sn *html.Node, n *html.Node) {
- if sn.Parent != nil {
- sn.Parent.InsertBefore(n, sn.NextSibling)
- }
- })
-}
-
-// Append appends the elements specified by the selector to the end of each element
-// in the set of matched elements, following those rules:
-//
-// 1) The selector is applied to the root document.
-//
-// 2) Elements that are part of the document will be moved to the new location.
-//
-// 3) If there are multiple locations to append to, cloned nodes will be
-// appended to all target locations except the last one, which will be moved
-// as noted in (2).
-func (s *Selection) Append(selector string) *Selection {
- return s.AppendMatcher(compileMatcher(selector))
-}
-
-// AppendMatcher appends the elements specified by the matcher to the end of each element
-// in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) AppendMatcher(m Matcher) *Selection {
- return s.AppendNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// AppendSelection appends the elements in the selection to the end of each element
-// in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) AppendSelection(sel *Selection) *Selection {
- return s.AppendNodes(sel.Nodes...)
-}
-
-// AppendHtml parses the html and appends it to the set of matched elements.
-func (s *Selection) AppendHtml(html string) *Selection {
- return s.AppendNodes(parseHtml(html)...)
-}
-
-// AppendNodes appends the specified nodes to each node in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) AppendNodes(ns ...*html.Node) *Selection {
- return s.manipulateNodes(ns, false, func(sn *html.Node, n *html.Node) {
- sn.AppendChild(n)
- })
-}
-
-// Before inserts the matched elements before each element in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) Before(selector string) *Selection {
- return s.BeforeMatcher(compileMatcher(selector))
-}
-
-// BeforeMatcher inserts the matched elements before each element in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) BeforeMatcher(m Matcher) *Selection {
- return s.BeforeNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// BeforeSelection inserts the elements in the selection before each element in the set of matched
-// elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) BeforeSelection(sel *Selection) *Selection {
- return s.BeforeNodes(sel.Nodes...)
-}
-
-// BeforeHtml parses the html and inserts it before the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) BeforeHtml(html string) *Selection {
- return s.BeforeNodes(parseHtml(html)...)
-}
-
-// BeforeNodes inserts the nodes before each element in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) BeforeNodes(ns ...*html.Node) *Selection {
- return s.manipulateNodes(ns, false, func(sn *html.Node, n *html.Node) {
- if sn.Parent != nil {
- sn.Parent.InsertBefore(n, sn)
- }
- })
-}
-
-// Clone creates a deep copy of the set of matched nodes. The new nodes will not be
-// attached to the document.
-func (s *Selection) Clone() *Selection {
- ns := newEmptySelection(s.document)
- ns.Nodes = cloneNodes(s.Nodes)
- return ns
-}
-
-// Empty removes all children nodes from the set of matched elements.
-// It returns the children nodes in a new Selection.
-func (s *Selection) Empty() *Selection {
- var nodes []*html.Node
-
- for _, n := range s.Nodes {
- for c := n.FirstChild; c != nil; c = n.FirstChild {
- n.RemoveChild(c)
- nodes = append(nodes, c)
- }
- }
-
- return pushStack(s, nodes)
-}
-
-// Prepend prepends the elements specified by the selector to each element in
-// the set of matched elements, following the same rules as Append.
-func (s *Selection) Prepend(selector string) *Selection {
- return s.PrependMatcher(compileMatcher(selector))
-}
-
-// PrependMatcher prepends the elements specified by the matcher to each
-// element in the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) PrependMatcher(m Matcher) *Selection {
- return s.PrependNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// PrependSelection prepends the elements in the selection to each element in
-// the set of matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) PrependSelection(sel *Selection) *Selection {
- return s.PrependNodes(sel.Nodes...)
-}
-
-// PrependHtml parses the html and prepends it to the set of matched elements.
-func (s *Selection) PrependHtml(html string) *Selection {
- return s.PrependNodes(parseHtml(html)...)
-}
-
-// PrependNodes prepends the specified nodes to each node in the set of
-// matched elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) PrependNodes(ns ...*html.Node) *Selection {
- return s.manipulateNodes(ns, true, func(sn *html.Node, n *html.Node) {
- // sn.FirstChild may be nil, in which case this functions like
- // sn.AppendChild()
- sn.InsertBefore(n, sn.FirstChild)
- })
-}
-
-// Remove removes the set of matched elements from the document.
-// It returns the same selection, now consisting of nodes not in the document.
-func (s *Selection) Remove() *Selection {
- for _, n := range s.Nodes {
- if n.Parent != nil {
- n.Parent.RemoveChild(n)
- }
- }
-
- return s
-}
-
-// RemoveFiltered removes the set of matched elements by selector.
-// It returns the Selection of removed nodes.
-func (s *Selection) RemoveFiltered(selector string) *Selection {
- return s.RemoveMatcher(compileMatcher(selector))
-}
-
-// RemoveMatcher removes the set of matched elements.
-// It returns the Selection of removed nodes.
-func (s *Selection) RemoveMatcher(m Matcher) *Selection {
- return s.FilterMatcher(m).Remove()
-}
-
-// ReplaceWith replaces each element in the set of matched elements with the
-// nodes matched by the given selector.
-// It returns the removed elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) ReplaceWith(selector string) *Selection {
- return s.ReplaceWithMatcher(compileMatcher(selector))
-}
-
-// ReplaceWithMatcher replaces each element in the set of matched elements with
-// the nodes matched by the given Matcher.
-// It returns the removed elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) ReplaceWithMatcher(m Matcher) *Selection {
- return s.ReplaceWithNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// ReplaceWithSelection replaces each element in the set of matched elements with
-// the nodes from the given Selection.
-// It returns the removed elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) ReplaceWithSelection(sel *Selection) *Selection {
- return s.ReplaceWithNodes(sel.Nodes...)
-}
-
-// ReplaceWithHtml replaces each element in the set of matched elements with
-// the parsed HTML.
-// It returns the removed elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) ReplaceWithHtml(html string) *Selection {
- return s.ReplaceWithNodes(parseHtml(html)...)
-}
-
-// ReplaceWithNodes replaces each element in the set of matched elements with
-// the given nodes.
-// It returns the removed elements.
-//
-// This follows the same rules as Selection.Append.
-func (s *Selection) ReplaceWithNodes(ns ...*html.Node) *Selection {
- s.AfterNodes(ns...)
- return s.Remove()
-}
-
-// SetHtml sets the html content of each element in the selection to
-// specified html string.
-func (s *Selection) SetHtml(html string) *Selection {
- return setHtmlNodes(s, parseHtml(html)...)
-}
-
-// SetText sets the content of each element in the selection to specified content.
-// The provided text string is escaped.
-func (s *Selection) SetText(text string) *Selection {
- return s.SetHtml(html.EscapeString(text))
-}
-
-// Unwrap removes the parents of the set of matched elements, leaving the matched
-// elements (and their siblings, if any) in their place.
-// It returns the original selection.
-func (s *Selection) Unwrap() *Selection {
- s.Parent().Each(func(i int, ss *Selection) {
- // For some reason, jquery allows unwrap to remove the element, so
- // allowing it here too. Same for . Why it allows those elements to
- // be unwrapped while not allowing body is a mystery to me.
- if ss.Nodes[0].Data != "body" {
- ss.ReplaceWithSelection(ss.Contents())
- }
- })
-
- return s
-}
-
-// Wrap wraps each element in the set of matched elements inside the first
-// element matched by the given selector. The matched child is cloned before
-// being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) Wrap(selector string) *Selection {
- return s.WrapMatcher(compileMatcher(selector))
-}
-
-// WrapMatcher wraps each element in the set of matched elements inside the
-// first element matched by the given matcher. The matched child is cloned
-// before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapMatcher(m Matcher) *Selection {
- return s.wrapNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// WrapSelection wraps each element in the set of matched elements inside the
-// first element in the given Selection. The element is cloned before being
-// inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapSelection(sel *Selection) *Selection {
- return s.wrapNodes(sel.Nodes...)
-}
-
-// WrapHtml wraps each element in the set of matched elements inside the inner-
-// most child of the given HTML.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapHtml(html string) *Selection {
- return s.wrapNodes(parseHtml(html)...)
-}
-
-// WrapNode wraps each element in the set of matched elements inside the inner-
-// most child of the given node. The given node is copied before being inserted
-// into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapNode(n *html.Node) *Selection {
- return s.wrapNodes(n)
-}
-
-func (s *Selection) wrapNodes(ns ...*html.Node) *Selection {
- s.Each(func(i int, ss *Selection) {
- ss.wrapAllNodes(ns...)
- })
-
- return s
-}
-
-// WrapAll wraps a single HTML structure, matched by the given selector, around
-// all elements in the set of matched elements. The matched child is cloned
-// before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapAll(selector string) *Selection {
- return s.WrapAllMatcher(compileMatcher(selector))
-}
-
-// WrapAllMatcher wraps a single HTML structure, matched by the given Matcher,
-// around all elements in the set of matched elements. The matched child is
-// cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapAllMatcher(m Matcher) *Selection {
- return s.wrapAllNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// WrapAllSelection wraps a single HTML structure, the first node of the given
-// Selection, around all elements in the set of matched elements. The matched
-// child is cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapAllSelection(sel *Selection) *Selection {
- return s.wrapAllNodes(sel.Nodes...)
-}
-
-// WrapAllHtml wraps the given HTML structure around all elements in the set of
-// matched elements. The matched child is cloned before being inserted into the
-// document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapAllHtml(html string) *Selection {
- return s.wrapAllNodes(parseHtml(html)...)
-}
-
-func (s *Selection) wrapAllNodes(ns ...*html.Node) *Selection {
- if len(ns) > 0 {
- return s.WrapAllNode(ns[0])
- }
- return s
-}
-
-// WrapAllNode wraps the given node around the first element in the Selection,
-// making all other nodes in the Selection children of the given node. The node
-// is cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapAllNode(n *html.Node) *Selection {
- if s.Size() == 0 {
- return s
- }
-
- wrap := cloneNode(n)
-
- first := s.Nodes[0]
- if first.Parent != nil {
- first.Parent.InsertBefore(wrap, first)
- first.Parent.RemoveChild(first)
- }
-
- for c := getFirstChildEl(wrap); c != nil; c = getFirstChildEl(wrap) {
- wrap = c
- }
-
- newSingleSelection(wrap, s.document).AppendSelection(s)
-
- return s
-}
-
-// WrapInner wraps an HTML structure, matched by the given selector, around the
-// content of element in the set of matched elements. The matched child is
-// cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapInner(selector string) *Selection {
- return s.WrapInnerMatcher(compileMatcher(selector))
-}
-
-// WrapInnerMatcher wraps an HTML structure, matched by the given selector,
-// around the content of element in the set of matched elements. The matched
-// child is cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapInnerMatcher(m Matcher) *Selection {
- return s.wrapInnerNodes(m.MatchAll(s.document.rootNode)...)
-}
-
-// WrapInnerSelection wraps an HTML structure, matched by the given selector,
-// around the content of element in the set of matched elements. The matched
-// child is cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapInnerSelection(sel *Selection) *Selection {
- return s.wrapInnerNodes(sel.Nodes...)
-}
-
-// WrapInnerHtml wraps an HTML structure, matched by the given selector, around
-// the content of element in the set of matched elements. The matched child is
-// cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapInnerHtml(html string) *Selection {
- return s.wrapInnerNodes(parseHtml(html)...)
-}
-
-// WrapInnerNode wraps an HTML structure, matched by the given selector, around
-// the content of element in the set of matched elements. The matched child is
-// cloned before being inserted into the document.
-//
-// It returns the original set of elements.
-func (s *Selection) WrapInnerNode(n *html.Node) *Selection {
- return s.wrapInnerNodes(n)
-}
-
-func (s *Selection) wrapInnerNodes(ns ...*html.Node) *Selection {
- if len(ns) == 0 {
- return s
- }
-
- s.Each(func(i int, s *Selection) {
- contents := s.Contents()
-
- if contents.Size() > 0 {
- contents.wrapAllNodes(ns...)
- } else {
- s.AppendNodes(cloneNode(ns[0]))
- }
- })
-
- return s
-}
-
-func parseHtml(h string) []*html.Node {
- // Errors are only returned when the io.Reader returns any error besides
- // EOF, but strings.Reader never will
- nodes, err := html.ParseFragment(strings.NewReader(h), &html.Node{Type: html.ElementNode})
- if err != nil {
- panic("goquery: failed to parse HTML: " + err.Error())
- }
- return nodes
-}
-
-func setHtmlNodes(s *Selection, ns ...*html.Node) *Selection {
- for _, n := range s.Nodes {
- for c := n.FirstChild; c != nil; c = n.FirstChild {
- n.RemoveChild(c)
- }
- for _, c := range ns {
- n.AppendChild(cloneNode(c))
- }
- }
- return s
-}
-
-// Get the first child that is an ElementNode
-func getFirstChildEl(n *html.Node) *html.Node {
- c := n.FirstChild
- for c != nil && c.Type != html.ElementNode {
- c = c.NextSibling
- }
- return c
-}
-
-// Deep copy a slice of nodes.
-func cloneNodes(ns []*html.Node) []*html.Node {
- cns := make([]*html.Node, 0, len(ns))
-
- for _, n := range ns {
- cns = append(cns, cloneNode(n))
- }
-
- return cns
-}
-
-// Deep copy a node. The new node has clones of all the original node's
-// children but none of its parents or siblings.
-func cloneNode(n *html.Node) *html.Node {
- nn := &html.Node{
- Type: n.Type,
- DataAtom: n.DataAtom,
- Data: n.Data,
- Attr: make([]html.Attribute, len(n.Attr)),
- }
-
- copy(nn.Attr, n.Attr)
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- nn.AppendChild(cloneNode(c))
- }
-
- return nn
-}
-
-func (s *Selection) manipulateNodes(ns []*html.Node, reverse bool,
- f func(sn *html.Node, n *html.Node)) *Selection {
-
- lasti := s.Size() - 1
-
- // net.Html doesn't provide document fragments for insertion, so to get
- // things in the correct order with After() and Prepend(), the callback
- // needs to be called on the reverse of the nodes.
- if reverse {
- for i, j := 0, len(ns)-1; i < j; i, j = i+1, j-1 {
- ns[i], ns[j] = ns[j], ns[i]
- }
- }
-
- for i, sn := range s.Nodes {
- for _, n := range ns {
- if i != lasti {
- f(sn, cloneNode(n))
- } else {
- if n.Parent != nil {
- n.Parent.RemoveChild(n)
- }
- f(sn, n)
- }
- }
- }
-
- return s
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/property.go b/vendor/github.com/PuerkitoBio/goquery/property.go
deleted file mode 100644
index 411126db..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/property.go
+++ /dev/null
@@ -1,275 +0,0 @@
-package goquery
-
-import (
- "bytes"
- "regexp"
- "strings"
-
- "golang.org/x/net/html"
-)
-
-var rxClassTrim = regexp.MustCompile("[\t\r\n]")
-
-// 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 (s *Selection) Attr(attrName string) (val string, exists bool) {
- if len(s.Nodes) == 0 {
- return
- }
- return getAttributeValue(attrName, s.Nodes[0])
-}
-
-// AttrOr works like Attr but returns default value if attribute is not present.
-func (s *Selection) AttrOr(attrName, defaultValue string) string {
- if len(s.Nodes) == 0 {
- return defaultValue
- }
-
- val, exists := getAttributeValue(attrName, s.Nodes[0])
- if !exists {
- return defaultValue
- }
-
- return val
-}
-
-// RemoveAttr removes the named attribute from each element in the set of matched elements.
-func (s *Selection) RemoveAttr(attrName string) *Selection {
- for _, n := range s.Nodes {
- removeAttr(n, attrName)
- }
-
- return s
-}
-
-// SetAttr sets the given attribute on each element in the set of matched elements.
-func (s *Selection) SetAttr(attrName, val string) *Selection {
- for _, n := range s.Nodes {
- attr := getAttributePtr(attrName, n)
- if attr == nil {
- n.Attr = append(n.Attr, html.Attribute{Key: attrName, Val: val})
- } else {
- attr.Val = val
- }
- }
-
- return s
-}
-
-// Text gets the combined text contents of each element in the set of matched
-// elements, including their descendants.
-func (s *Selection) Text() string {
- var buf bytes.Buffer
-
- // Slightly optimized vs calling Each: no single selection object created
- var f func(*html.Node)
- f = func(n *html.Node) {
- if n.Type == html.TextNode {
- // Keep newlines and spaces, like jQuery
- buf.WriteString(n.Data)
- }
- if n.FirstChild != nil {
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- f(c)
- }
- }
- }
- for _, n := range s.Nodes {
- f(n)
- }
-
- return buf.String()
-}
-
-// 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 (s *Selection) Length() int {
- return len(s.Nodes)
-}
-
-// Html gets the HTML contents of the first element in the set of matched
-// elements. It includes text and comment nodes.
-func (s *Selection) Html() (ret string, e error) {
- // Since there is no .innerHtml, the HTML content must be re-created from
- // the nodes using html.Render.
- var buf bytes.Buffer
-
- 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
- }
- }
- ret = buf.String()
- }
-
- return
-}
-
-// AddClass adds the given class(es) to each element in the set of matched elements.
-// Multiple class names can be specified, separated by a space or via multiple arguments.
-func (s *Selection) AddClass(class ...string) *Selection {
- classStr := strings.TrimSpace(strings.Join(class, " "))
-
- if classStr == "" {
- return s
- }
-
- tcls := getClassesSlice(classStr)
- for _, n := range s.Nodes {
- curClasses, attr := getClassesAndAttr(n, true)
- for _, newClass := range tcls {
- if !strings.Contains(curClasses, " "+newClass+" ") {
- curClasses += newClass + " "
- }
- }
-
- setClasses(n, attr, curClasses)
- }
-
- return s
-}
-
-// HasClass determines whether any of the matched elements are assigned the
-// given class.
-func (s *Selection) HasClass(class string) bool {
- class = " " + class + " "
- for _, n := range s.Nodes {
- classes, _ := getClassesAndAttr(n, false)
- if strings.Contains(classes, class) {
- return true
- }
- }
- return false
-}
-
-// RemoveClass removes the given class(es) from each element in the set of matched elements.
-// Multiple class names can be specified, separated by a space or via multiple arguments.
-// If no class name is provided, all classes are removed.
-func (s *Selection) RemoveClass(class ...string) *Selection {
- var rclasses []string
-
- classStr := strings.TrimSpace(strings.Join(class, " "))
- remove := classStr == ""
-
- if !remove {
- rclasses = getClassesSlice(classStr)
- }
-
- for _, n := range s.Nodes {
- if remove {
- removeAttr(n, "class")
- } else {
- classes, attr := getClassesAndAttr(n, true)
- for _, rcl := range rclasses {
- classes = strings.Replace(classes, " "+rcl+" ", " ", -1)
- }
-
- setClasses(n, attr, classes)
- }
- }
-
- return s
-}
-
-// ToggleClass adds or removes the given class(es) for each element in the set of matched elements.
-// Multiple class names can be specified, separated by a space or via multiple arguments.
-func (s *Selection) ToggleClass(class ...string) *Selection {
- classStr := strings.TrimSpace(strings.Join(class, " "))
-
- if classStr == "" {
- return s
- }
-
- tcls := getClassesSlice(classStr)
-
- for _, n := range s.Nodes {
- classes, attr := getClassesAndAttr(n, true)
- for _, tcl := range tcls {
- if strings.Contains(classes, " "+tcl+" ") {
- classes = strings.Replace(classes, " "+tcl+" ", " ", -1)
- } else {
- classes += tcl + " "
- }
- }
-
- setClasses(n, attr, classes)
- }
-
- return s
-}
-
-func getAttributePtr(attrName string, n *html.Node) *html.Attribute {
- if n == nil {
- return nil
- }
-
- for i, a := range n.Attr {
- if a.Key == attrName {
- return &n.Attr[i]
- }
- }
- return nil
-}
-
-// Private function to get the specified attribute's value from a node.
-func getAttributeValue(attrName string, n *html.Node) (val string, exists bool) {
- if a := getAttributePtr(attrName, n); a != nil {
- val = a.Val
- exists = true
- }
- return
-}
-
-// Get and normalize the "class" attribute from the node.
-func getClassesAndAttr(n *html.Node, create bool) (classes string, attr *html.Attribute) {
- // Applies only to element nodes
- if n.Type == html.ElementNode {
- attr = getAttributePtr("class", n)
- if attr == nil && create {
- n.Attr = append(n.Attr, html.Attribute{
- Key: "class",
- Val: "",
- })
- attr = &n.Attr[len(n.Attr)-1]
- }
- }
-
- if attr == nil {
- classes = " "
- } else {
- classes = rxClassTrim.ReplaceAllString(" "+attr.Val+" ", " ")
- }
-
- return
-}
-
-func getClassesSlice(classes string) []string {
- return strings.Split(rxClassTrim.ReplaceAllString(" "+classes+" ", " "), " ")
-}
-
-func removeAttr(n *html.Node, attrName string) {
- for i, a := range n.Attr {
- if a.Key == attrName {
- n.Attr[i], n.Attr[len(n.Attr)-1], n.Attr =
- n.Attr[len(n.Attr)-1], html.Attribute{}, n.Attr[:len(n.Attr)-1]
- return
- }
- }
-}
-
-func setClasses(n *html.Node, attr *html.Attribute, classes string) {
- classes = strings.TrimSpace(classes)
- if classes == "" {
- removeAttr(n, "class")
- return
- }
-
- attr.Val = classes
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/query.go b/vendor/github.com/PuerkitoBio/goquery/query.go
deleted file mode 100644
index fe86bf0b..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/query.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package goquery
-
-import "golang.org/x/net/html"
-
-// Is checks the current matched set of elements against a selector and
-// returns true if at least one of these elements matches.
-func (s *Selection) Is(selector string) bool {
- return s.IsMatcher(compileMatcher(selector))
-}
-
-// IsMatcher checks the current matched set of elements against a matcher and
-// returns true if at least one of these elements matches.
-func (s *Selection) IsMatcher(m Matcher) bool {
- if len(s.Nodes) > 0 {
- if len(s.Nodes) == 1 {
- return m.Match(s.Nodes[0])
- }
- return len(m.Filter(s.Nodes)) > 0
- }
-
- return false
-}
-
-// IsFunction checks the current matched set of elements against a predicate and
-// returns true if at least one of these elements matches.
-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
-// and returns true if at least one of these elements matches.
-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
-// and returns true if at least one of these elements matches.
-func (s *Selection) IsNodes(nodes ...*html.Node) bool {
- return s.FilterNodes(nodes...).Length() > 0
-}
-
-// 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
-// node is itself in the selection, it returns false.
-func (s *Selection) Contains(n *html.Node) bool {
- return sliceContains(s.Nodes, n)
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/traversal.go b/vendor/github.com/PuerkitoBio/goquery/traversal.go
deleted file mode 100644
index 5fa5315a..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/traversal.go
+++ /dev/null
@@ -1,698 +0,0 @@
-package goquery
-
-import "golang.org/x/net/html"
-
-type siblingType int
-
-// Sibling type, used internally when iterating over children at the same
-// level (siblings) to specify which nodes are requested.
-const (
- siblingPrevUntil siblingType = iota - 3
- siblingPrevAll
- siblingPrev
- siblingAll
- siblingNext
- siblingNextAll
- siblingNextUntil
- siblingAllIncludingNonElements
-)
-
-// 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 (s *Selection) Find(selector string) *Selection {
- return pushStack(s, findWithMatcher(s.Nodes, compileMatcher(selector)))
-}
-
-// FindMatcher gets the descendants of each element in the current set of matched
-// elements, filtered by the matcher. It returns a new Selection object
-// containing these matched elements.
-func (s *Selection) FindMatcher(m Matcher) *Selection {
- return pushStack(s, findWithMatcher(s.Nodes, m))
-}
-
-// 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 (s *Selection) FindSelection(sel *Selection) *Selection {
- if sel == nil {
- return pushStack(s, nil)
- }
- return s.FindNodes(sel.Nodes...)
-}
-
-// 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 (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,
-// including text and comment nodes. It returns a new Selection object
-// containing these elements.
-func (s *Selection) Contents() *Selection {
- return pushStack(s, getChildrenNodes(s.Nodes, siblingAllIncludingNonElements))
-}
-
-// 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 (s *Selection) ContentsFiltered(selector string) *Selection {
- if selector != "" {
- return s.ChildrenFiltered(selector)
- }
- return s.Contents()
-}
-
-// ContentsMatcher gets the children of each element in the Selection,
-// filtered by the specified matcher. It returns a new Selection
-// object containing these elements. Since matchers only act on Element nodes,
-// this function is an alias to ChildrenMatcher.
-func (s *Selection) ContentsMatcher(m Matcher) *Selection {
- return s.ChildrenMatcher(m)
-}
-
-// Children gets the child elements of each element in the Selection.
-// It returns a new Selection object containing these elements.
-func (s *Selection) Children() *Selection {
- return pushStack(s, getChildrenNodes(s.Nodes, siblingAll))
-}
-
-// 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 (s *Selection) ChildrenFiltered(selector string) *Selection {
- return filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), compileMatcher(selector))
-}
-
-// ChildrenMatcher gets the child elements of each element in the Selection,
-// filtered by the specified matcher. It returns a new
-// Selection object containing these elements.
-func (s *Selection) ChildrenMatcher(m Matcher) *Selection {
- return filterAndPush(s, getChildrenNodes(s.Nodes, siblingAll), m)
-}
-
-// Parent gets the parent of each element in the Selection. It returns a
-// new Selection object containing the matched elements.
-func (s *Selection) Parent() *Selection {
- return pushStack(s, getParentNodes(s.Nodes))
-}
-
-// 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 (s *Selection) ParentFiltered(selector string) *Selection {
- return filterAndPush(s, getParentNodes(s.Nodes), compileMatcher(selector))
-}
-
-// ParentMatcher gets the parent of each element in the Selection filtered by a
-// matcher. It returns a new Selection object containing the matched elements.
-func (s *Selection) ParentMatcher(m Matcher) *Selection {
- return filterAndPush(s, getParentNodes(s.Nodes), m)
-}
-
-// 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 (s *Selection) Closest(selector string) *Selection {
- cs := compileMatcher(selector)
- return s.ClosestMatcher(cs)
-}
-
-// ClosestMatcher gets the first element that matches the matcher by testing the
-// element itself and traversing up through its ancestors in the DOM tree.
-func (s *Selection) ClosestMatcher(m Matcher) *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 {
- if m.Match(n) {
- return []*html.Node{n}
- }
- }
- return nil
- }))
-}
-
-// 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 (s *Selection) ClosestNodes(nodes ...*html.Node) *Selection {
- set := make(map[*html.Node]bool)
- for _, n := range nodes {
- set[n] = true
- }
- 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 {
- if set[n] {
- return []*html.Node{n}
- }
- }
- return nil
- }))
-}
-
-// 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 (s *Selection) ClosestSelection(sel *Selection) *Selection {
- if sel == nil {
- return pushStack(s, nil)
- }
- return s.ClosestNodes(sel.Nodes...)
-}
-
-// Parents gets the ancestors of each element in the current Selection. It
-// returns a new Selection object with the matched elements.
-func (s *Selection) Parents() *Selection {
- return pushStack(s, getParentsNodes(s.Nodes, nil, nil))
-}
-
-// ParentsFiltered gets the ancestors of each element in the current
-// Selection. It returns a new Selection object with the matched elements.
-func (s *Selection) ParentsFiltered(selector string) *Selection {
- return filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), compileMatcher(selector))
-}
-
-// ParentsMatcher gets the ancestors of each element in the current
-// Selection. It returns a new Selection object with the matched elements.
-func (s *Selection) ParentsMatcher(m Matcher) *Selection {
- return filterAndPush(s, getParentsNodes(s.Nodes, nil, nil), m)
-}
-
-// 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 (s *Selection) ParentsUntil(selector string) *Selection {
- return pushStack(s, getParentsNodes(s.Nodes, compileMatcher(selector), nil))
-}
-
-// ParentsUntilMatcher gets the ancestors of each element in the Selection, up to but
-// not including the element matched by the matcher. It returns a new Selection
-// object containing the matched elements.
-func (s *Selection) ParentsUntilMatcher(m Matcher) *Selection {
- return pushStack(s, getParentsNodes(s.Nodes, m, nil))
-}
-
-// 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 (s *Selection) ParentsUntilSelection(sel *Selection) *Selection {
- if sel == nil {
- return s.Parents()
- }
- return s.ParentsUntilNodes(sel.Nodes...)
-}
-
-// 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 (s *Selection) ParentsUntilNodes(nodes ...*html.Node) *Selection {
- return pushStack(s, getParentsNodes(s.Nodes, nil, nodes))
-}
-
-// 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 (s *Selection) ParentsFilteredUntil(filterSelector, untilSelector string) *Selection {
- return filterAndPush(s, getParentsNodes(s.Nodes, compileMatcher(untilSelector), nil), compileMatcher(filterSelector))
-}
-
-// ParentsFilteredUntilMatcher is like ParentsUntilMatcher, with the option to filter the
-// results based on a matcher. It returns a new Selection object containing the matched elements.
-func (s *Selection) ParentsFilteredUntilMatcher(filter, until Matcher) *Selection {
- return filterAndPush(s, getParentsNodes(s.Nodes, until, nil), filter)
-}
-
-// 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 (s *Selection) ParentsFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
- return s.ParentsMatcherUntilSelection(compileMatcher(filterSelector), sel)
-}
-
-// ParentsMatcherUntilSelection is like ParentsUntilSelection, with the
-// option to filter the results based on a matcher. It returns a new
-// Selection object containing the matched elements.
-func (s *Selection) ParentsMatcherUntilSelection(filter Matcher, sel *Selection) *Selection {
- if sel == nil {
- return s.ParentsMatcher(filter)
- }
- return s.ParentsMatcherUntilNodes(filter, sel.Nodes...)
-}
-
-// 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 (s *Selection) ParentsFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
- return filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), compileMatcher(filterSelector))
-}
-
-// ParentsMatcherUntilNodes is like ParentsUntilNodes, with the
-// option to filter the results based on a matcher. It returns a new
-// Selection object containing the matched elements.
-func (s *Selection) ParentsMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {
- return filterAndPush(s, getParentsNodes(s.Nodes, nil, nodes), filter)
-}
-
-// Siblings gets the siblings of each element in the Selection. It returns
-// a new Selection object containing the matched elements.
-func (s *Selection) Siblings() *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil))
-}
-
-// 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 (s *Selection) SiblingsFiltered(selector string) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), compileMatcher(selector))
-}
-
-// SiblingsMatcher gets the siblings of each element in the Selection
-// filtered by a matcher. It returns a new Selection object containing the
-// matched elements.
-func (s *Selection) SiblingsMatcher(m Matcher) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingAll, nil, nil), m)
-}
-
-// Next gets the immediately following sibling of each element in the
-// Selection. It returns a new Selection object containing the matched elements.
-func (s *Selection) Next() *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil))
-}
-
-// 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 (s *Selection) NextFiltered(selector string) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), compileMatcher(selector))
-}
-
-// NextMatcher gets the immediately following sibling of each element in the
-// Selection filtered by a matcher. It returns a new Selection object
-// containing the matched elements.
-func (s *Selection) NextMatcher(m Matcher) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), m)
-}
-
-// NextAll gets all the following siblings of each element in the
-// Selection. It returns a new Selection object containing the matched elements.
-func (s *Selection) NextAll() *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil))
-}
-
-// 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 (s *Selection) NextAllFiltered(selector string) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), compileMatcher(selector))
-}
-
-// NextAllMatcher gets all the following siblings of each element in the
-// Selection filtered by a matcher. It returns a new Selection object
-// containing the matched elements.
-func (s *Selection) NextAllMatcher(m Matcher) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextAll, nil, nil), m)
-}
-
-// Prev gets the immediately preceding sibling of each element in the
-// Selection. It returns a new Selection object containing the matched elements.
-func (s *Selection) Prev() *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil))
-}
-
-// 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 (s *Selection) PrevFiltered(selector string) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), compileMatcher(selector))
-}
-
-// PrevMatcher gets the immediately preceding sibling of each element in the
-// Selection filtered by a matcher. It returns a new Selection object
-// containing the matched elements.
-func (s *Selection) PrevMatcher(m Matcher) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrev, nil, nil), m)
-}
-
-// PrevAll gets all the preceding siblings of each element in the
-// Selection. It returns a new Selection object containing the matched elements.
-func (s *Selection) PrevAll() *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil))
-}
-
-// 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 (s *Selection) PrevAllFiltered(selector string) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), compileMatcher(selector))
-}
-
-// PrevAllMatcher gets all the preceding siblings of each element in the
-// Selection filtered by a matcher. It returns a new Selection object
-// containing the matched elements.
-func (s *Selection) PrevAllMatcher(m Matcher) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevAll, nil, nil), m)
-}
-
-// 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 (s *Selection) NextUntil(selector string) *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
- compileMatcher(selector), nil))
-}
-
-// NextUntilMatcher gets all following siblings of each element up to but not
-// including the element matched by the matcher. It returns a new Selection
-// object containing the matched elements.
-func (s *Selection) NextUntilMatcher(m Matcher) *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
- m, nil))
-}
-
-// 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 (s *Selection) NextUntilSelection(sel *Selection) *Selection {
- if sel == nil {
- return s.NextAll()
- }
- return s.NextUntilNodes(sel.Nodes...)
-}
-
-// 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 (s *Selection) NextUntilNodes(nodes ...*html.Node) *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
- nil, nodes))
-}
-
-// 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 (s *Selection) PrevUntil(selector string) *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
- compileMatcher(selector), nil))
-}
-
-// PrevUntilMatcher gets all preceding siblings of each element up to but not
-// including the element matched by the matcher. It returns a new Selection
-// object containing the matched elements.
-func (s *Selection) PrevUntilMatcher(m Matcher) *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
- m, nil))
-}
-
-// 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 (s *Selection) PrevUntilSelection(sel *Selection) *Selection {
- if sel == nil {
- return s.PrevAll()
- }
- return s.PrevUntilNodes(sel.Nodes...)
-}
-
-// 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 (s *Selection) PrevUntilNodes(nodes ...*html.Node) *Selection {
- return pushStack(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
- nil, nodes))
-}
-
-// 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 (s *Selection) NextFilteredUntil(filterSelector, untilSelector string) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
- compileMatcher(untilSelector), nil), compileMatcher(filterSelector))
-}
-
-// NextFilteredUntilMatcher is like NextUntilMatcher, with the option to filter
-// the results based on a matcher.
-// It returns a new Selection object containing the matched elements.
-func (s *Selection) NextFilteredUntilMatcher(filter, until Matcher) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
- until, nil), filter)
-}
-
-// 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 (s *Selection) NextFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
- return s.NextMatcherUntilSelection(compileMatcher(filterSelector), sel)
-}
-
-// NextMatcherUntilSelection is like NextUntilSelection, with the
-// option to filter the results based on a matcher. It returns a new
-// Selection object containing the matched elements.
-func (s *Selection) NextMatcherUntilSelection(filter Matcher, sel *Selection) *Selection {
- if sel == nil {
- return s.NextMatcher(filter)
- }
- return s.NextMatcherUntilNodes(filter, sel.Nodes...)
-}
-
-// 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 (s *Selection) NextFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
- nil, nodes), compileMatcher(filterSelector))
-}
-
-// NextMatcherUntilNodes is like NextUntilNodes, with the
-// option to filter the results based on a matcher. It returns a new
-// Selection object containing the matched elements.
-func (s *Selection) NextMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNextUntil,
- nil, nodes), 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 (s *Selection) PrevFilteredUntil(filterSelector, untilSelector string) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
- compileMatcher(untilSelector), nil), compileMatcher(filterSelector))
-}
-
-// PrevFilteredUntilMatcher is like PrevUntilMatcher, with the option to filter
-// the results based on a matcher.
-// It returns a new Selection object containing the matched elements.
-func (s *Selection) PrevFilteredUntilMatcher(filter, until Matcher) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
- until, nil), filter)
-}
-
-// 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 (s *Selection) PrevFilteredUntilSelection(filterSelector string, sel *Selection) *Selection {
- return s.PrevMatcherUntilSelection(compileMatcher(filterSelector), sel)
-}
-
-// PrevMatcherUntilSelection is like PrevUntilSelection, with the
-// option to filter the results based on a matcher. It returns a new
-// Selection object containing the matched elements.
-func (s *Selection) PrevMatcherUntilSelection(filter Matcher, sel *Selection) *Selection {
- if sel == nil {
- return s.PrevMatcher(filter)
- }
- return s.PrevMatcherUntilNodes(filter, sel.Nodes...)
-}
-
-// 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 (s *Selection) PrevFilteredUntilNodes(filterSelector string, nodes ...*html.Node) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
- nil, nodes), compileMatcher(filterSelector))
-}
-
-// PrevMatcherUntilNodes is like PrevUntilNodes, with the
-// option to filter the results based on a matcher. It returns a new
-// Selection object containing the matched elements.
-func (s *Selection) PrevMatcherUntilNodes(filter Matcher, nodes ...*html.Node) *Selection {
- return filterAndPush(s, getSiblingNodes(s.Nodes, siblingPrevUntil,
- nil, nodes), filter)
-}
-
-// Filter and push filters the nodes based on a matcher, and pushes the results
-// on the stack, with the srcSel as previous selection.
-func filterAndPush(srcSel *Selection, nodes []*html.Node, m Matcher) *Selection {
- // Create a temporary Selection with the specified nodes to filter using winnow
- sel := &Selection{nodes, srcSel.document, nil}
- // Filter based on matcher and push on stack
- return pushStack(srcSel, winnow(sel, m, true))
-}
-
-// Internal implementation of Find that return raw nodes.
-func findWithMatcher(nodes []*html.Node, m Matcher) []*html.Node {
- // 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
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- if c.Type == html.ElementNode {
- result = append(result, m.MatchAll(c)...)
- }
- }
- return
- })
-}
-
-// Internal implementation to get all parent nodes, stopping at the specified
-// node (or nil if no stop).
-func getParentsNodes(nodes []*html.Node, stopm Matcher, stopNodes []*html.Node) []*html.Node {
- return mapNodes(nodes, func(i int, n *html.Node) (result []*html.Node) {
- for p := n.Parent; p != nil; p = p.Parent {
- sel := newSingleSelection(p, nil)
- if stopm != nil {
- if sel.IsMatcher(stopm) {
- break
- }
- } else if len(stopNodes) > 0 {
- if sel.IsNodes(stopNodes...) {
- break
- }
- }
- if p.Type == html.ElementNode {
- result = append(result, p)
- }
- }
- return
- })
-}
-
-// Internal implementation of sibling nodes that return a raw slice of matches.
-func getSiblingNodes(nodes []*html.Node, st siblingType, untilm Matcher, untilNodes []*html.Node) []*html.Node {
- var f func(*html.Node) bool
-
- // 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 {
- if untilm != nil {
- // Matcher-based condition
- sel := newSingleSelection(n, nil)
- return sel.IsMatcher(untilm)
- } else if len(untilNodes) > 0 {
- // Nodes-based condition
- sel := newSingleSelection(n, nil)
- return sel.IsNodes(untilNodes...)
- }
- return false
- }
- }
-
- return mapNodes(nodes, func(i int, n *html.Node) []*html.Node {
- return getChildrenWithSiblingType(n.Parent, st, n, f)
- })
-}
-
-// Gets the children nodes of each node in the specified slice of nodes,
-// based on the sibling type request.
-func getChildrenNodes(nodes []*html.Node, st siblingType) []*html.Node {
- return mapNodes(nodes, func(i int, n *html.Node) []*html.Node {
- return getChildrenWithSiblingType(n, st, nil, nil)
- })
-}
-
-// Gets the children of the specified parent, based on the requested sibling
-// type, skipping a specified node if required.
-func getChildrenWithSiblingType(parent *html.Node, st siblingType, skipNode *html.Node,
- untilFunc func(*html.Node) bool) (result []*html.Node) {
-
- // Create the iterator function
- var iter = func(cur *html.Node) (ret *html.Node) {
- // Based on the sibling type requested, iterate the right way
- for {
- switch st {
- case siblingAll, siblingAllIncludingNonElements:
- if cur == nil {
- // First iteration, start with first child of parent
- // Skip node if required
- if ret = parent.FirstChild; ret == skipNode && skipNode != nil {
- ret = skipNode.NextSibling
- }
- } else {
- // Skip node if required
- if ret = cur.NextSibling; ret == skipNode && skipNode != nil {
- ret = skipNode.NextSibling
- }
- }
- case siblingPrev, siblingPrevAll, siblingPrevUntil:
- if cur == nil {
- // Start with previous sibling of the skip node
- ret = skipNode.PrevSibling
- } else {
- ret = cur.PrevSibling
- }
- case siblingNext, siblingNextAll, siblingNextUntil:
- if cur == nil {
- // Start with next sibling of the skip node
- ret = skipNode.NextSibling
- } else {
- ret = cur.NextSibling
- }
- default:
- panic("Invalid sibling type.")
- }
- if ret == nil || ret.Type == html.ElementNode || st == siblingAllIncludingNonElements {
- return
- }
- // Not a valid node, try again from this one
- cur = ret
- }
- }
-
- for c := iter(nil); c != nil; c = iter(c) {
- // 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) {
- return
- }
- }
- result = append(result, c)
- if st == siblingNext || st == siblingPrev {
- // Only one node was requested (immediate next or previous), so exit
- return
- }
- }
- return
-}
-
-// Internal implementation of parent nodes that return a raw slice of Nodes.
-func getParentNodes(nodes []*html.Node) []*html.Node {
- return mapNodes(nodes, func(i int, n *html.Node) []*html.Node {
- if n.Parent != nil && n.Parent.Type == html.ElementNode {
- return []*html.Node{n.Parent}
- }
- return nil
- })
-}
-
-// Internal map function used by many traversing methods. Takes the source nodes
-// to iterate on and the mapping function that returns an array of nodes.
-// Returns an array of nodes mapped by calling the callback function once for
-// each node in the source nodes.
-func mapNodes(nodes []*html.Node, f func(int, *html.Node) []*html.Node) (result []*html.Node) {
- set := make(map[*html.Node]bool)
- for i, n := range nodes {
- if vals := f(i, n); len(vals) > 0 {
- result = appendWithoutDuplicates(result, vals, set)
- }
- }
- return result
-}
diff --git a/vendor/github.com/PuerkitoBio/goquery/type.go b/vendor/github.com/PuerkitoBio/goquery/type.go
deleted file mode 100644
index 6ad51dbc..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/type.go
+++ /dev/null
@@ -1,141 +0,0 @@
-package goquery
-
-import (
- "errors"
- "io"
- "net/http"
- "net/url"
-
- "github.com/andybalholm/cascadia"
-
- "golang.org/x/net/html"
-)
-
-// Document represents an HTML document to be manipulated. Unlike jQuery, which
-// is loaded as part of a DOM document, and thus acts upon its containing
-// document, GoQuery doesn't know which HTML document to act upon. So it needs
-// to be told, and that's what the Document class is for. It holds the root
-// document node to manipulate, and can make selections on this document.
-type Document struct {
- *Selection
- Url *url.URL
- rootNode *html.Node
-}
-
-// NewDocumentFromNode is a Document constructor that takes a root html Node
-// as argument.
-func NewDocumentFromNode(root *html.Node) *Document {
- return newDocument(root, nil)
-}
-
-// 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.
-//
-// Deprecated: Use the net/http standard library package to make the request
-// and validate the response before calling goquery.NewDocumentFromReader
-// with the response's body.
-func NewDocument(url string) (*Document, error) {
- // Load the URL
- res, e := http.Get(url)
- if e != nil {
- return nil, e
- }
- return NewDocumentFromResponse(res)
-}
-
-// NewDocumentFromReader returns a Document from an io.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, 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) (*Document, error) {
- root, e := html.Parse(r)
- if e != nil {
- return nil, e
- }
- return newDocument(root, nil), nil
-}
-
-// NewDocumentFromResponse is another Document constructor that takes an http response as argument.
-// It loads the specified response's document, parses it, and stores the root Document
-// node, ready to be manipulated. The response's body is closed on return.
-//
-// Deprecated: Use goquery.NewDocumentFromReader with the response's body.
-func NewDocumentFromResponse(res *http.Response) (*Document, error) {
- if res == nil {
- return nil, errors.New("Response is nil")
- }
- defer res.Body.Close()
- if res.Request == nil {
- return nil, errors.New("Response.Request is nil")
- }
-
- // Parse the HTML into nodes
- root, e := html.Parse(res.Body)
- if e != nil {
- return nil, e
- }
-
- // Create and fill the document
- return newDocument(root, res.Request.URL), nil
-}
-
-// CloneDocument creates a deep-clone of a document.
-func CloneDocument(doc *Document) *Document {
- return newDocument(cloneNode(doc.rootNode), doc.Url)
-}
-
-// Private constructor, make sure all fields are correctly filled.
-func newDocument(root *html.Node, url *url.URL) *Document {
- // Create and fill the document
- d := &Document{nil, url, root}
- d.Selection = newSingleSelection(root, d)
- return d
-}
-
-// Selection represents a collection of nodes matching some criteria. The
-// 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
- document *Document
- prevSel *Selection
-}
-
-// Helper constructor to create an empty selection
-func newEmptySelection(doc *Document) *Selection {
- return &Selection{nil, doc, nil}
-}
-
-// Helper constructor to create a selection of only one node
-func newSingleSelection(node *html.Node, doc *Document) *Selection {
- return &Selection{[]*html.Node{node}, doc, nil}
-}
-
-// Matcher is an interface that defines the methods to match
-// HTML nodes against a compiled selector string. Cascadia's
-// Selector implements this interface.
-type Matcher interface {
- Match(*html.Node) bool
- MatchAll(*html.Node) []*html.Node
- Filter([]*html.Node) []*html.Node
-}
-
-// compileMatcher compiles the selector string s and returns
-// the corresponding Matcher. If s is an invalid selector string,
-// it returns a Matcher that fails all matches.
-func compileMatcher(s string) Matcher {
- cs, err := cascadia.Compile(s)
- if err != nil {
- return invalidMatcher{}
- }
- return cs
-}
-
-// invalidMatcher is a Matcher that always fails to match.
-type invalidMatcher struct{}
-
-func (invalidMatcher) Match(n *html.Node) bool { return false }
-func (invalidMatcher) MatchAll(n *html.Node) []*html.Node { return nil }
-func (invalidMatcher) Filter(ns []*html.Node) []*html.Node { return nil }
diff --git a/vendor/github.com/PuerkitoBio/goquery/utilities.go b/vendor/github.com/PuerkitoBio/goquery/utilities.go
deleted file mode 100644
index b4c061a4..00000000
--- a/vendor/github.com/PuerkitoBio/goquery/utilities.go
+++ /dev/null
@@ -1,161 +0,0 @@
-package goquery
-
-import (
- "bytes"
-
- "golang.org/x/net/html"
-)
-
-// used to determine if a set (map[*html.Node]bool) should be used
-// instead of iterating over a slice. The set uses more memory and
-// is slower than slice iteration for small N.
-const minNodesForSet = 1000
-
-var nodeNames = []string{
- html.ErrorNode: "#error",
- html.TextNode: "#text",
- html.DocumentNode: "#document",
- html.CommentNode: "#comment",
-}
-
-// NodeName returns the node name of the first element in the selection.
-// It tries to behave in a similar way as the DOM's nodeName property
-// (https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeName).
-//
-// Go's net/html package defines the following node types, listed with
-// the corresponding returned value from this function:
-//
-// ErrorNode : #error
-// TextNode : #text
-// DocumentNode : #document
-// ElementNode : the element's tag name
-// CommentNode : #comment
-// DoctypeNode : the name of the document type
-//
-func NodeName(s *Selection) string {
- if s.Length() == 0 {
- return ""
- }
- switch n := s.Get(0); n.Type {
- case html.ElementNode, html.DoctypeNode:
- return n.Data
- default:
- if n.Type >= 0 && int(n.Type) < len(nodeNames) {
- return nodeNames[n.Type]
- }
- return ""
- }
-}
-
-// OuterHtml returns the outer HTML rendering of the first item in
-// the selection - that is, the HTML including the first element's
-// tag and attributes.
-//
-// Unlike InnerHtml, this is a function and not a method on the Selection,
-// because this is not a jQuery method (in javascript-land, this is
-// a property provided by the DOM).
-func OuterHtml(s *Selection) (string, error) {
- var buf bytes.Buffer
-
- if s.Length() == 0 {
- return "", nil
- }
- n := s.Get(0)
- if err := html.Render(&buf, n); err != nil {
- return "", err
- }
- return buf.String(), nil
-}
-
-// Loop through all container nodes to search for the target node.
-func sliceContains(container []*html.Node, contained *html.Node) bool {
- for _, n := range container {
- if nodeContains(n, contained) {
- return true
- }
- }
-
- return false
-}
-
-// Checks if the contained node is within the container node.
-func nodeContains(container *html.Node, contained *html.Node) bool {
- // Check if the parent of the contained node is the container node, traversing
- // upward until the top is reached, or the container is found.
- for contained = contained.Parent; contained != nil; contained = contained.Parent {
- if container == contained {
- return true
- }
- }
- return false
-}
-
-// Checks if the target node is in the slice of nodes.
-func isInSlice(slice []*html.Node, node *html.Node) bool {
- return indexInSlice(slice, node) > -1
-}
-
-// Returns the index of the target node in the slice, or -1.
-func indexInSlice(slice []*html.Node, node *html.Node) int {
- if node != nil {
- for i, n := range slice {
- if n == node {
- return i
- }
- }
- }
- return -1
-}
-
-// Appends the new nodes to the target slice, making sure no duplicate is added.
-// 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. If targetSet is nil, a local set is created with the
-// target if len(target) + len(nodes) is greater than minNodesForSet.
-func appendWithoutDuplicates(target []*html.Node, nodes []*html.Node, targetSet map[*html.Node]bool) []*html.Node {
- // if there are not that many nodes, don't use the map, faster to just use nested loops
- // (unless a non-nil targetSet is passed, in which case the caller knows better).
- if targetSet == nil && len(target)+len(nodes) < minNodesForSet {
- for _, n := range nodes {
- if !isInSlice(target, n) {
- target = append(target, n)
- }
- }
- return target
- }
-
- // if a targetSet is passed, then assume it is reliable, otherwise create one
- // and initialize it with the current target contents.
- if targetSet == nil {
- targetSet = make(map[*html.Node]bool, len(target))
- for _, n := range target {
- targetSet[n] = true
- }
- }
- for _, n := range nodes {
- if !targetSet[n] {
- target = append(target, n)
- targetSet[n] = true
- }
- }
-
- return target
-}
-
-// 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 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) *Selection {
- result := &Selection{nodes, fromSel.document, fromSel}
- return result
-}
diff --git a/vendor/github.com/StackExchange/wmi/LICENSE b/vendor/github.com/StackExchange/wmi/LICENSE
deleted file mode 100644
index ae80b672..00000000
--- a/vendor/github.com/StackExchange/wmi/LICENSE
+++ /dev/null
@@ -1,20 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Stack Exchange
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/StackExchange/wmi/README.md b/vendor/github.com/StackExchange/wmi/README.md
deleted file mode 100644
index 426d1a46..00000000
--- a/vendor/github.com/StackExchange/wmi/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-wmi
-===
-
-Package wmi provides a WQL interface to Windows WMI.
-
-Note: It interfaces with WMI on the local machine, therefore it only runs on Windows.
diff --git a/vendor/github.com/StackExchange/wmi/swbemservices.go b/vendor/github.com/StackExchange/wmi/swbemservices.go
deleted file mode 100644
index 9765a53f..00000000
--- a/vendor/github.com/StackExchange/wmi/swbemservices.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// +build windows
-
-package wmi
-
-import (
- "fmt"
- "reflect"
- "runtime"
- "sync"
-
- "github.com/go-ole/go-ole"
- "github.com/go-ole/go-ole/oleutil"
-)
-
-// SWbemServices is used to access wmi. See https://msdn.microsoft.com/en-us/library/aa393719(v=vs.85).aspx
-type SWbemServices struct {
- //TODO: track namespace. Not sure if we can re connect to a different namespace using the same instance
- cWMIClient *Client //This could also be an embedded struct, but then we would need to branch on Client vs SWbemServices in the Query method
- sWbemLocatorIUnknown *ole.IUnknown
- sWbemLocatorIDispatch *ole.IDispatch
- queries chan *queryRequest
- closeError chan error
- lQueryorClose sync.Mutex
-}
-
-type queryRequest struct {
- query string
- dst interface{}
- args []interface{}
- finished chan error
-}
-
-// InitializeSWbemServices will return a new SWbemServices object that can be used to query WMI
-func InitializeSWbemServices(c *Client, connectServerArgs ...interface{}) (*SWbemServices, error) {
- //fmt.Println("InitializeSWbemServices: Starting")
- //TODO: implement connectServerArgs as optional argument for init with connectServer call
- s := new(SWbemServices)
- s.cWMIClient = c
- s.queries = make(chan *queryRequest)
- initError := make(chan error)
- go s.process(initError)
-
- err, ok := <-initError
- if ok {
- return nil, err //Send error to caller
- }
- //fmt.Println("InitializeSWbemServices: Finished")
- return s, nil
-}
-
-// Close will clear and release all of the SWbemServices resources
-func (s *SWbemServices) Close() error {
- s.lQueryorClose.Lock()
- if s == nil || s.sWbemLocatorIDispatch == nil {
- s.lQueryorClose.Unlock()
- return fmt.Errorf("SWbemServices is not Initialized")
- }
- if s.queries == nil {
- s.lQueryorClose.Unlock()
- return fmt.Errorf("SWbemServices has been closed")
- }
- //fmt.Println("Close: sending close request")
- var result error
- ce := make(chan error)
- s.closeError = ce //Race condition if multiple callers to close. May need to lock here
- close(s.queries) //Tell background to shut things down
- s.lQueryorClose.Unlock()
- err, ok := <-ce
- if ok {
- result = err
- }
- //fmt.Println("Close: finished")
- return result
-}
-
-func (s *SWbemServices) process(initError chan error) {
- //fmt.Println("process: starting background thread initialization")
- //All OLE/WMI calls must happen on the same initialized thead, so lock this goroutine
- runtime.LockOSThread()
- defer runtime.LockOSThread()
-
- err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
- if err != nil {
- oleCode := err.(*ole.OleError).Code()
- if oleCode != ole.S_OK && oleCode != S_FALSE {
- initError <- fmt.Errorf("ole.CoInitializeEx error: %v", err)
- return
- }
- }
- defer ole.CoUninitialize()
-
- unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
- if err != nil {
- initError <- fmt.Errorf("CreateObject SWbemLocator error: %v", err)
- return
- } else if unknown == nil {
- initError <- ErrNilCreateObject
- return
- }
- defer unknown.Release()
- s.sWbemLocatorIUnknown = unknown
-
- dispatch, err := s.sWbemLocatorIUnknown.QueryInterface(ole.IID_IDispatch)
- if err != nil {
- initError <- fmt.Errorf("SWbemLocator QueryInterface error: %v", err)
- return
- }
- defer dispatch.Release()
- s.sWbemLocatorIDispatch = dispatch
-
- // we can't do the ConnectServer call outside the loop unless we find a way to track and re-init the connectServerArgs
- //fmt.Println("process: initialized. closing initError")
- close(initError)
- //fmt.Println("process: waiting for queries")
- for q := range s.queries {
- //fmt.Printf("process: new query: len(query)=%d\n", len(q.query))
- errQuery := s.queryBackground(q)
- //fmt.Println("process: s.queryBackground finished")
- if errQuery != nil {
- q.finished <- errQuery
- }
- close(q.finished)
- }
- //fmt.Println("process: queries channel closed")
- s.queries = nil //set channel to nil so we know it is closed
- //TODO: I think the Release/Clear calls can panic if things are in a bad state.
- //TODO: May need to recover from panics and send error to method caller instead.
- close(s.closeError)
-}
-
-// Query runs the WQL query using a SWbemServices instance and appends the values to dst.
-//
-// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
-// the query must have the same name in dst. Supported types are all signed and
-// unsigned integers, time.Time, string, bool, or a pointer to one of those.
-// Array types are not supported.
-//
-// By default, the local machine and default namespace are used. These can be
-// changed using connectServerArgs. See
-// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
-func (s *SWbemServices) Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
- s.lQueryorClose.Lock()
- if s == nil || s.sWbemLocatorIDispatch == nil {
- s.lQueryorClose.Unlock()
- return fmt.Errorf("SWbemServices is not Initialized")
- }
- if s.queries == nil {
- s.lQueryorClose.Unlock()
- return fmt.Errorf("SWbemServices has been closed")
- }
-
- //fmt.Println("Query: Sending query request")
- qr := queryRequest{
- query: query,
- dst: dst,
- args: connectServerArgs,
- finished: make(chan error),
- }
- s.queries <- &qr
- s.lQueryorClose.Unlock()
- err, ok := <-qr.finished
- if ok {
- //fmt.Println("Query: Finished with error")
- return err //Send error to caller
- }
- //fmt.Println("Query: Finished")
- return nil
-}
-
-func (s *SWbemServices) queryBackground(q *queryRequest) error {
- if s == nil || s.sWbemLocatorIDispatch == nil {
- return fmt.Errorf("SWbemServices is not Initialized")
- }
- wmi := s.sWbemLocatorIDispatch //Should just rename in the code, but this will help as we break things apart
- //fmt.Println("queryBackground: Starting")
-
- dv := reflect.ValueOf(q.dst)
- if dv.Kind() != reflect.Ptr || dv.IsNil() {
- return ErrInvalidEntityType
- }
- dv = dv.Elem()
- mat, elemType := checkMultiArg(dv)
- if mat == multiArgTypeInvalid {
- return ErrInvalidEntityType
- }
-
- // service is a SWbemServices
- serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", q.args...)
- if err != nil {
- return err
- }
- service := serviceRaw.ToIDispatch()
- defer serviceRaw.Clear()
-
- // result is a SWBemObjectSet
- resultRaw, err := oleutil.CallMethod(service, "ExecQuery", q.query)
- if err != nil {
- return err
- }
- result := resultRaw.ToIDispatch()
- defer resultRaw.Clear()
-
- count, err := oleInt64(result, "Count")
- if err != nil {
- return err
- }
-
- enumProperty, err := result.GetProperty("_NewEnum")
- if err != nil {
- return err
- }
- defer enumProperty.Clear()
-
- enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
- if err != nil {
- return err
- }
- if enum == nil {
- return fmt.Errorf("can't get IEnumVARIANT, enum is nil")
- }
- defer enum.Release()
-
- // Initialize a slice with Count capacity
- dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count)))
-
- var errFieldMismatch error
- for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) {
- if err != nil {
- return err
- }
-
- err := func() error {
- // item is a SWbemObject, but really a Win32_Process
- item := itemRaw.ToIDispatch()
- defer item.Release()
-
- ev := reflect.New(elemType)
- if err = s.cWMIClient.loadEntity(ev.Interface(), item); err != nil {
- if _, ok := err.(*ErrFieldMismatch); ok {
- // We continue loading entities even in the face of field mismatch errors.
- // If we encounter any other error, that other error is returned. Otherwise,
- // an ErrFieldMismatch is returned.
- errFieldMismatch = err
- } else {
- return err
- }
- }
- if mat != multiArgTypeStructPtr {
- ev = ev.Elem()
- }
- dv.Set(reflect.Append(dv, ev))
- return nil
- }()
- if err != nil {
- return err
- }
- }
- //fmt.Println("queryBackground: Finished")
- return errFieldMismatch
-}
diff --git a/vendor/github.com/StackExchange/wmi/wmi.go b/vendor/github.com/StackExchange/wmi/wmi.go
deleted file mode 100644
index a951b125..00000000
--- a/vendor/github.com/StackExchange/wmi/wmi.go
+++ /dev/null
@@ -1,486 +0,0 @@
-// +build windows
-
-/*
-Package wmi provides a WQL interface for WMI on Windows.
-
-Example code to print names of running processes:
-
- type Win32_Process struct {
- Name string
- }
-
- func main() {
- var dst []Win32_Process
- q := wmi.CreateQuery(&dst, "")
- err := wmi.Query(q, &dst)
- if err != nil {
- log.Fatal(err)
- }
- for i, v := range dst {
- println(i, v.Name)
- }
- }
-
-*/
-package wmi
-
-import (
- "bytes"
- "errors"
- "fmt"
- "log"
- "os"
- "reflect"
- "runtime"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "github.com/go-ole/go-ole"
- "github.com/go-ole/go-ole/oleutil"
-)
-
-var l = log.New(os.Stdout, "", log.LstdFlags)
-
-var (
- ErrInvalidEntityType = errors.New("wmi: invalid entity type")
- // ErrNilCreateObject is the error returned if CreateObject returns nil even
- // if the error was nil.
- ErrNilCreateObject = errors.New("wmi: create object returned nil")
- lock sync.Mutex
-)
-
-// S_FALSE is returned by CoInitializeEx if it was already called on this thread.
-const S_FALSE = 0x00000001
-
-// QueryNamespace invokes Query with the given namespace on the local machine.
-func QueryNamespace(query string, dst interface{}, namespace string) error {
- return Query(query, dst, nil, namespace)
-}
-
-// Query runs the WQL query and appends the values to dst.
-//
-// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
-// the query must have the same name in dst. Supported types are all signed and
-// unsigned integers, time.Time, string, bool, or a pointer to one of those.
-// Array types are not supported.
-//
-// By default, the local machine and default namespace are used. These can be
-// changed using connectServerArgs. See
-// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
-//
-// Query is a wrapper around DefaultClient.Query.
-func Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
- if DefaultClient.SWbemServicesClient == nil {
- return DefaultClient.Query(query, dst, connectServerArgs...)
- }
- return DefaultClient.SWbemServicesClient.Query(query, dst, connectServerArgs...)
-}
-
-// A Client is an WMI query client.
-//
-// Its zero value (DefaultClient) is a usable client.
-type Client struct {
- // NonePtrZero specifies if nil values for fields which aren't pointers
- // should be returned as the field types zero value.
- //
- // Setting this to true allows stucts without pointer fields to be used
- // without the risk failure should a nil value returned from WMI.
- NonePtrZero bool
-
- // PtrNil specifies if nil values for pointer fields should be returned
- // as nil.
- //
- // Setting this to true will set pointer fields to nil where WMI
- // returned nil, otherwise the types zero value will be returned.
- PtrNil bool
-
- // AllowMissingFields specifies that struct fields not present in the
- // query result should not result in an error.
- //
- // Setting this to true allows custom queries to be used with full
- // struct definitions instead of having to define multiple structs.
- AllowMissingFields bool
-
- // SWbemServiceClient is an optional SWbemServices object that can be
- // initialized and then reused across multiple queries. If it is null
- // then the method will initialize a new temporary client each time.
- SWbemServicesClient *SWbemServices
-}
-
-// DefaultClient is the default Client and is used by Query, QueryNamespace
-var DefaultClient = &Client{}
-
-// Query runs the WQL query and appends the values to dst.
-//
-// dst must have type *[]S or *[]*S, for some struct type S. Fields selected in
-// the query must have the same name in dst. Supported types are all signed and
-// unsigned integers, time.Time, string, bool, or a pointer to one of those.
-// Array types are not supported.
-//
-// By default, the local machine and default namespace are used. These can be
-// changed using connectServerArgs. See
-// http://msdn.microsoft.com/en-us/library/aa393720.aspx for details.
-func (c *Client) Query(query string, dst interface{}, connectServerArgs ...interface{}) error {
- dv := reflect.ValueOf(dst)
- if dv.Kind() != reflect.Ptr || dv.IsNil() {
- return ErrInvalidEntityType
- }
- dv = dv.Elem()
- mat, elemType := checkMultiArg(dv)
- if mat == multiArgTypeInvalid {
- return ErrInvalidEntityType
- }
-
- lock.Lock()
- defer lock.Unlock()
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
-
- err := ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
- if err != nil {
- oleCode := err.(*ole.OleError).Code()
- if oleCode != ole.S_OK && oleCode != S_FALSE {
- return err
- }
- }
- defer ole.CoUninitialize()
-
- unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator")
- if err != nil {
- return err
- } else if unknown == nil {
- return ErrNilCreateObject
- }
- defer unknown.Release()
-
- wmi, err := unknown.QueryInterface(ole.IID_IDispatch)
- if err != nil {
- return err
- }
- defer wmi.Release()
-
- // service is a SWbemServices
- serviceRaw, err := oleutil.CallMethod(wmi, "ConnectServer", connectServerArgs...)
- if err != nil {
- return err
- }
- service := serviceRaw.ToIDispatch()
- defer serviceRaw.Clear()
-
- // result is a SWBemObjectSet
- resultRaw, err := oleutil.CallMethod(service, "ExecQuery", query)
- if err != nil {
- return err
- }
- result := resultRaw.ToIDispatch()
- defer resultRaw.Clear()
-
- count, err := oleInt64(result, "Count")
- if err != nil {
- return err
- }
-
- enumProperty, err := result.GetProperty("_NewEnum")
- if err != nil {
- return err
- }
- defer enumProperty.Clear()
-
- enum, err := enumProperty.ToIUnknown().IEnumVARIANT(ole.IID_IEnumVariant)
- if err != nil {
- return err
- }
- if enum == nil {
- return fmt.Errorf("can't get IEnumVARIANT, enum is nil")
- }
- defer enum.Release()
-
- // Initialize a slice with Count capacity
- dv.Set(reflect.MakeSlice(dv.Type(), 0, int(count)))
-
- var errFieldMismatch error
- for itemRaw, length, err := enum.Next(1); length > 0; itemRaw, length, err = enum.Next(1) {
- if err != nil {
- return err
- }
-
- err := func() error {
- // item is a SWbemObject, but really a Win32_Process
- item := itemRaw.ToIDispatch()
- defer item.Release()
-
- ev := reflect.New(elemType)
- if err = c.loadEntity(ev.Interface(), item); err != nil {
- if _, ok := err.(*ErrFieldMismatch); ok {
- // We continue loading entities even in the face of field mismatch errors.
- // If we encounter any other error, that other error is returned. Otherwise,
- // an ErrFieldMismatch is returned.
- errFieldMismatch = err
- } else {
- return err
- }
- }
- if mat != multiArgTypeStructPtr {
- ev = ev.Elem()
- }
- dv.Set(reflect.Append(dv, ev))
- return nil
- }()
- if err != nil {
- return err
- }
- }
- return errFieldMismatch
-}
-
-// ErrFieldMismatch is returned when a field is to be loaded into a different
-// type than the one it was stored from, or when a field is missing or
-// unexported in the destination struct.
-// StructType is the type of the struct pointed to by the destination argument.
-type ErrFieldMismatch struct {
- StructType reflect.Type
- FieldName string
- Reason string
-}
-
-func (e *ErrFieldMismatch) Error() string {
- return fmt.Sprintf("wmi: cannot load field %q into a %q: %s",
- e.FieldName, e.StructType, e.Reason)
-}
-
-var timeType = reflect.TypeOf(time.Time{})
-
-// loadEntity loads a SWbemObject into a struct pointer.
-func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismatch error) {
- v := reflect.ValueOf(dst).Elem()
- for i := 0; i < v.NumField(); i++ {
- f := v.Field(i)
- of := f
- isPtr := f.Kind() == reflect.Ptr
- if isPtr {
- ptr := reflect.New(f.Type().Elem())
- f.Set(ptr)
- f = f.Elem()
- }
- n := v.Type().Field(i).Name
- if !f.CanSet() {
- return &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: "CanSet() is false",
- }
- }
- prop, err := oleutil.GetProperty(src, n)
- if err != nil {
- if !c.AllowMissingFields {
- errFieldMismatch = &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: "no such struct field",
- }
- }
- continue
- }
- defer prop.Clear()
-
- switch val := prop.Value().(type) {
- case int8, int16, int32, int64, int:
- v := reflect.ValueOf(val).Int()
- switch f.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- f.SetInt(v)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- f.SetUint(uint64(v))
- default:
- return &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: "not an integer class",
- }
- }
- case uint8, uint16, uint32, uint64:
- v := reflect.ValueOf(val).Uint()
- switch f.Kind() {
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- f.SetInt(int64(v))
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- f.SetUint(v)
- default:
- return &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: "not an integer class",
- }
- }
- case string:
- switch f.Kind() {
- case reflect.String:
- f.SetString(val)
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- iv, err := strconv.ParseInt(val, 10, 64)
- if err != nil {
- return err
- }
- f.SetInt(iv)
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- uv, err := strconv.ParseUint(val, 10, 64)
- if err != nil {
- return err
- }
- f.SetUint(uv)
- case reflect.Struct:
- switch f.Type() {
- case timeType:
- if len(val) == 25 {
- mins, err := strconv.Atoi(val[22:])
- if err != nil {
- return err
- }
- val = val[:22] + fmt.Sprintf("%02d%02d", mins/60, mins%60)
- }
- t, err := time.Parse("20060102150405.000000-0700", val)
- if err != nil {
- return err
- }
- f.Set(reflect.ValueOf(t))
- }
- }
- case bool:
- switch f.Kind() {
- case reflect.Bool:
- f.SetBool(val)
- default:
- return &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: "not a bool",
- }
- }
- case float32:
- switch f.Kind() {
- case reflect.Float32:
- f.SetFloat(float64(val))
- default:
- return &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: "not a Float32",
- }
- }
- default:
- if f.Kind() == reflect.Slice {
- switch f.Type().Elem().Kind() {
- case reflect.String:
- safeArray := prop.ToArray()
- if safeArray != nil {
- arr := safeArray.ToValueArray()
- fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr))
- for i, v := range arr {
- s := fArr.Index(i)
- s.SetString(v.(string))
- }
- f.Set(fArr)
- }
- case reflect.Uint8:
- safeArray := prop.ToArray()
- if safeArray != nil {
- arr := safeArray.ToValueArray()
- fArr := reflect.MakeSlice(f.Type(), len(arr), len(arr))
- for i, v := range arr {
- s := fArr.Index(i)
- s.SetUint(reflect.ValueOf(v).Uint())
- }
- f.Set(fArr)
- }
- default:
- return &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: fmt.Sprintf("unsupported slice type (%T)", val),
- }
- }
- } else {
- typeof := reflect.TypeOf(val)
- if typeof == nil && (isPtr || c.NonePtrZero) {
- if (isPtr && c.PtrNil) || (!isPtr && c.NonePtrZero) {
- of.Set(reflect.Zero(of.Type()))
- }
- break
- }
- return &ErrFieldMismatch{
- StructType: of.Type(),
- FieldName: n,
- Reason: fmt.Sprintf("unsupported type (%T)", val),
- }
- }
- }
- }
- return errFieldMismatch
-}
-
-type multiArgType int
-
-const (
- multiArgTypeInvalid multiArgType = iota
- multiArgTypeStruct
- multiArgTypeStructPtr
-)
-
-// checkMultiArg checks that v has type []S, []*S for some struct type S.
-//
-// It returns what category the slice's elements are, and the reflect.Type
-// that represents S.
-func checkMultiArg(v reflect.Value) (m multiArgType, elemType reflect.Type) {
- if v.Kind() != reflect.Slice {
- return multiArgTypeInvalid, nil
- }
- elemType = v.Type().Elem()
- switch elemType.Kind() {
- case reflect.Struct:
- return multiArgTypeStruct, elemType
- case reflect.Ptr:
- elemType = elemType.Elem()
- if elemType.Kind() == reflect.Struct {
- return multiArgTypeStructPtr, elemType
- }
- }
- return multiArgTypeInvalid, nil
-}
-
-func oleInt64(item *ole.IDispatch, prop string) (int64, error) {
- v, err := oleutil.GetProperty(item, prop)
- if err != nil {
- return 0, err
- }
- defer v.Clear()
-
- i := int64(v.Val)
- return i, nil
-}
-
-// CreateQuery returns a WQL query string that queries all columns of src. where
-// is an optional string that is appended to the query, to be used with WHERE
-// clauses. In such a case, the "WHERE" string should appear at the beginning.
-func CreateQuery(src interface{}, where string) string {
- var b bytes.Buffer
- b.WriteString("SELECT ")
- s := reflect.Indirect(reflect.ValueOf(src))
- t := s.Type()
- if s.Kind() == reflect.Slice {
- t = t.Elem()
- }
- if t.Kind() != reflect.Struct {
- return ""
- }
- var fields []string
- for i := 0; i < t.NumField(); i++ {
- fields = append(fields, t.Field(i).Name)
- }
- b.WriteString(strings.Join(fields, ", "))
- b.WriteString(" FROM ")
- b.WriteString(t.Name())
- b.WriteString(" " + where)
- return b.String()
-}
diff --git a/vendor/github.com/andybalholm/cascadia/.travis.yml b/vendor/github.com/andybalholm/cascadia/.travis.yml
deleted file mode 100644
index 6f227517..00000000
--- 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 ee5ad35a..00000000
--- 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 9021cb92..00000000
--- a/vendor/github.com/andybalholm/cascadia/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# cascadia
-
-[](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.
diff --git a/vendor/github.com/andybalholm/cascadia/go.mod b/vendor/github.com/andybalholm/cascadia/go.mod
deleted file mode 100644
index e6febbbf..00000000
--- a/vendor/github.com/andybalholm/cascadia/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module "github.com/andybalholm/cascadia"
-
-require "golang.org/x/net" v0.0.0-20180218175443-cbe0f9307d01
diff --git a/vendor/github.com/andybalholm/cascadia/parser.go b/vendor/github.com/andybalholm/cascadia/parser.go
deleted file mode 100644
index 495db9cc..00000000
--- a/vendor/github.com/andybalholm/cascadia/parser.go
+++ /dev/null
@@ -1,835 +0,0 @@
-// Package cascadia is an implementation of CSS selectors.
-package cascadia
-
-import (
- "errors"
- "fmt"
- "regexp"
- "strconv"
- "strings"
-
- "golang.org/x/net/html"
-)
-
-// a parser for CSS selectors
-type parser struct {
- s string // the source text
- i int // the current position
-}
-
-// 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 < p.i+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
-}
-
-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 Selector, err error) {
- tag, err := p.parseIdentifier()
- if err != nil {
- return nil, err
- }
-
- return typeSelector(tag), nil
-}
-
-// parseIDSelector parses a selector that matches by id attribute.
-func (p *parser) parseIDSelector() (Selector, error) {
- if p.i >= len(p.s) {
- return nil, fmt.Errorf("expected id selector (#id), found EOF instead")
- }
- if p.s[p.i] != '#' {
- return nil, fmt.Errorf("expected id selector (#id), found '%c' instead", p.s[p.i])
- }
-
- p.i++
- id, err := p.parseName()
- if err != nil {
- return nil, err
- }
-
- return attributeEqualsSelector("id", id), nil
-}
-
-// parseClassSelector parses a selector that matches by class attribute.
-func (p *parser) parseClassSelector() (Selector, error) {
- if p.i >= len(p.s) {
- return nil, fmt.Errorf("expected class selector (.class), found EOF instead")
- }
- if p.s[p.i] != '.' {
- return nil, fmt.Errorf("expected class selector (.class), found '%c' instead", p.s[p.i])
- }
-
- p.i++
- class, err := p.parseIdentifier()
- if err != nil {
- return nil, err
- }
-
- return attributeIncludesSelector("class", class), nil
-}
-
-// parseAttributeSelector parses a selector that matches by attribute value.
-func (p *parser) parseAttributeSelector() (Selector, error) {
- if p.i >= len(p.s) {
- return nil, fmt.Errorf("expected attribute selector ([attribute]), found EOF instead")
- }
- if p.s[p.i] != '[' {
- return nil, 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 nil, err
- }
-
- p.skipWhitespace()
- if p.i >= len(p.s) {
- return nil, errors.New("unexpected EOF in attribute selector")
- }
-
- if p.s[p.i] == ']' {
- p.i++
- return attributeExistsSelector(key), nil
- }
-
- if p.i+2 >= len(p.s) {
- return nil, errors.New("unexpected EOF in attribute selector")
- }
-
- op := p.s[p.i : p.i+2]
- if op[0] == '=' {
- op = "="
- } else if op[1] != '=' {
- return nil, fmt.Errorf(`expected equality operator, found "%s" instead`, op)
- }
- p.i += len(op)
-
- p.skipWhitespace()
- if p.i >= len(p.s) {
- return nil, 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 nil, err
- }
-
- p.skipWhitespace()
- if p.i >= len(p.s) {
- return nil, errors.New("unexpected EOF in attribute selector")
- }
- if p.s[p.i] != ']' {
- return nil, fmt.Errorf("expected ']', found '%c' instead", p.s[p.i])
- }
- p.i++
-
- switch op {
- case "=":
- return attributeEqualsSelector(key, val), nil
- case "!=":
- return attributeNotEqualSelector(key, val), nil
- case "~=":
- return attributeIncludesSelector(key, val), nil
- case "|=":
- return attributeDashmatchSelector(key, val), nil
- case "^=":
- return attributePrefixSelector(key, val), nil
- case "$=":
- return attributeSuffixSelector(key, val), nil
- case "*=":
- return attributeSubstringSelector(key, val), nil
- case "#=":
- return attributeRegexSelector(key, rx), nil
- }
-
- return nil, 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).
-func (p *parser) parsePseudoclassSelector() (Selector, 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++
- name, err := p.parseIdentifier()
- if err != nil {
- return nil, err
- }
- name = toLowerASCII(name)
-
- switch name {
- case "not", "has", "haschild":
- if !p.consumeParenthesis() {
- return nil, errExpectedParenthesis
- }
- sel, parseErr := p.parseSelectorGroup()
- if parseErr != nil {
- return nil, parseErr
- }
- if !p.consumeClosingParenthesis() {
- return nil, errExpectedClosingParenthesis
- }
-
- switch name {
- case "not":
- return negatedSelector(sel), nil
- case "has":
- return hasDescendantSelector(sel), nil
- case "haschild":
- return hasChildSelector(sel), nil
- }
-
- case "contains", "containsown":
- if !p.consumeParenthesis() {
- return nil, errExpectedParenthesis
- }
- if p.i == len(p.s) {
- return nil, errUnmatchedParenthesis
- }
- var val string
- switch p.s[p.i] {
- case '\'', '"':
- val, err = p.parseString()
- default:
- val, err = p.parseIdentifier()
- }
- if err != nil {
- return nil, err
- }
- val = strings.ToLower(val)
- p.skipWhitespace()
- if p.i >= len(p.s) {
- return nil, errors.New("unexpected EOF in pseudo selector")
- }
- if !p.consumeClosingParenthesis() {
- return nil, errExpectedClosingParenthesis
- }
-
- switch name {
- case "contains":
- return textSubstrSelector(val), nil
- case "containsown":
- return ownTextSubstrSelector(val), nil
- }
-
- case "matches", "matchesown":
- if !p.consumeParenthesis() {
- return nil, errExpectedParenthesis
- }
- rx, err := p.parseRegex()
- if err != nil {
- return nil, err
- }
- if p.i >= len(p.s) {
- return nil, errors.New("unexpected EOF in pseudo selector")
- }
- if !p.consumeClosingParenthesis() {
- return nil, errExpectedClosingParenthesis
- }
-
- switch name {
- case "matches":
- return textRegexSelector(rx), nil
- case "matchesown":
- return ownTextRegexSelector(rx), nil
- }
-
- case "nth-child", "nth-last-child", "nth-of-type", "nth-last-of-type":
- if !p.consumeParenthesis() {
- return nil, errExpectedParenthesis
- }
- a, b, err := p.parseNth()
- if err != nil {
- return nil, err
- }
- if !p.consumeClosingParenthesis() {
- return nil, errExpectedClosingParenthesis
- }
- if a == 0 {
- switch name {
- case "nth-child":
- return simpleNthChildSelector(b, false), nil
- case "nth-of-type":
- return simpleNthChildSelector(b, true), nil
- case "nth-last-child":
- return simpleNthLastChildSelector(b, false), nil
- case "nth-last-of-type":
- return simpleNthLastChildSelector(b, true), nil
- }
- }
- return nthChildSelector(a, b,
- name == "nth-last-child" || name == "nth-last-of-type",
- name == "nth-of-type" || name == "nth-last-of-type"),
- nil
-
- case "first-child":
- return simpleNthChildSelector(1, false), nil
- case "last-child":
- return simpleNthLastChildSelector(1, false), nil
- case "first-of-type":
- return simpleNthChildSelector(1, true), nil
- case "last-of-type":
- return simpleNthLastChildSelector(1, true), nil
- case "only-child":
- return onlyChildSelector(false), nil
- case "only-of-type":
- return onlyChildSelector(true), nil
- case "input":
- return inputSelector, nil
- case "empty":
- return emptyElementSelector, nil
- case "root":
- return rootSelector, nil
- }
-
- return nil, fmt.Errorf("unknown pseudoclass :%s", name)
-}
-
-// 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() (Selector, error) {
- var result Selector
-
- 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
- }
- result = r
- }
-
-loop:
- for p.i < len(p.s) {
- var ns Selector
- var err error
- switch p.s[p.i] {
- case '#':
- ns, err = p.parseIDSelector()
- case '.':
- ns, err = p.parseClassSelector()
- case '[':
- ns, err = p.parseAttributeSelector()
- case ':':
- ns, err = p.parsePseudoclassSelector()
- default:
- break loop
- }
- if err != nil {
- return nil, err
- }
- if result == nil {
- result = ns
- } else {
- result = intersectionSelector(result, ns)
- }
- }
-
- if result == nil {
- result = func(n *html.Node) bool {
- return n.Type == html.ElementNode
- }
- }
-
- return result, nil
-}
-
-// parseSelector parses a selector that may include combinators.
-func (p *parser) parseSelector() (result Selector, err error) {
- p.skipWhitespace()
- result, err = p.parseSimpleSelectorSequence()
- if err != nil {
- return
- }
-
- for {
- var combinator byte
- if p.skipWhitespace() {
- combinator = ' '
- }
- if p.i >= len(p.s) {
- return
- }
-
- 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
- }
-
- if combinator == 0 {
- return
- }
-
- c, err := p.parseSimpleSelectorSequence()
- if err != nil {
- return nil, err
- }
-
- switch combinator {
- case ' ':
- result = descendantSelector(result, c)
- case '>':
- result = childSelector(result, c)
- case '+':
- result = siblingSelector(result, c, true)
- case '~':
- result = siblingSelector(result, c, false)
- }
- }
-
- panic("unreachable")
-}
-
-// parseSelectorGroup parses a group of selectors, separated by commas.
-func (p *parser) parseSelectorGroup() (result Selector, err error) {
- result, err = p.parseSelector()
- if err != nil {
- return
- }
-
- for p.i < len(p.s) {
- if p.s[p.i] != ',' {
- return result, nil
- }
- p.i++
- c, err := p.parseSelector()
- if err != nil {
- return nil, err
- }
- result = unionSelector(result, c)
- }
-
- return
-}
diff --git a/vendor/github.com/andybalholm/cascadia/selector.go b/vendor/github.com/andybalholm/cascadia/selector.go
deleted file mode 100644
index 9fb05ccb..00000000
--- a/vendor/github.com/andybalholm/cascadia/selector.go
+++ /dev/null
@@ -1,622 +0,0 @@
-package cascadia
-
-import (
- "bytes"
- "fmt"
- "regexp"
- "strings"
-
- "golang.org/x/net/html"
-)
-
-// the Selector type, and functions for creating them
-
-// A Selector is a function which tells whether a node matches or not.
-type Selector func(*html.Node) bool
-
-// hasChildMatch returns whether n has any child that matches a.
-func hasChildMatch(n *html.Node, a Selector) bool {
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- if a(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 Selector) bool {
- for c := n.FirstChild; c != nil; c = c.NextSibling {
- if a(c) || (c.Type == html.ElementNode && hasDescendantMatch(c, a)) {
- return true
- }
- }
- return false
-}
-
-// 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) {
- 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
-}
-
-// 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
-}
-
-// 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
-}
-
-// 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
-}
-
-// typeSelector returns a Selector that matches elements with a given tag name.
-func typeSelector(tag string) Selector {
- tag = toLowerASCII(tag)
- return func(n *html.Node) bool {
- return n.Type == html.ElementNode && n.Data == tag
- }
-}
-
-// 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)
-}
-
-// attributeSelector returns a Selector that matches elements
-// where the attribute named key satisifes the function f.
-func attributeSelector(key string, f func(string) bool) Selector {
- key = toLowerASCII(key)
- return func(n *html.Node) bool {
- if n.Type != html.ElementNode {
- return false
- }
- for _, a := range n.Attr {
- if a.Key == key && f(a.Val) {
- return true
- }
- }
- return false
- }
-}
-
-// attributeExistsSelector returns a Selector that matches elements that have
-// an attribute named key.
-func attributeExistsSelector(key string) Selector {
- return attributeSelector(key, func(string) bool { return true })
-}
-
-// attributeEqualsSelector returns a Selector that matches elements where
-// the attribute named key has the value val.
-func attributeEqualsSelector(key, val string) Selector {
- return attributeSelector(key,
- func(s string) bool {
- return s == val
- })
-}
-
-// attributeNotEqualSelector returns a Selector that matches elements where
-// the attribute named key does not have the value val.
-func attributeNotEqualSelector(key, val string) Selector {
- key = toLowerASCII(key)
- return func(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
- }
-}
-
-// attributeIncludesSelector returns a Selector that matches elements where
-// the attribute named key is a whitespace-separated list that includes val.
-func attributeIncludesSelector(key, val string) Selector {
- return attributeSelector(key,
- func(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
- })
-}
-
-// attributeDashmatchSelector returns a Selector that matches elements where
-// the attribute named key equals val or starts with val plus a hyphen.
-func attributeDashmatchSelector(key, val string) Selector {
- return attributeSelector(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
- })
-}
-
-// attributePrefixSelector returns a Selector that matches elements where
-// the attribute named key starts with val.
-func attributePrefixSelector(key, val string) Selector {
- return attributeSelector(key,
- func(s string) bool {
- if strings.TrimSpace(s) == "" {
- return false
- }
- return strings.HasPrefix(s, val)
- })
-}
-
-// attributeSuffixSelector returns a Selector that matches elements where
-// the attribute named key ends with val.
-func attributeSuffixSelector(key, val string) Selector {
- return attributeSelector(key,
- func(s string) bool {
- if strings.TrimSpace(s) == "" {
- return false
- }
- return strings.HasSuffix(s, val)
- })
-}
-
-// attributeSubstringSelector returns a Selector that matches nodes where
-// the attribute named key contains val.
-func attributeSubstringSelector(key, val string) Selector {
- return attributeSelector(key,
- func(s string) bool {
- if strings.TrimSpace(s) == "" {
- return false
- }
- return strings.Contains(s, val)
- })
-}
-
-// attributeRegexSelector returns a Selector that matches nodes where
-// the attribute named key matches the regular expression rx
-func attributeRegexSelector(key string, rx *regexp.Regexp) Selector {
- return attributeSelector(key,
- func(s string) bool {
- return rx.MatchString(s)
- })
-}
-
-// intersectionSelector returns a selector that matches nodes that match
-// both a and b.
-func intersectionSelector(a, b Selector) Selector {
- return func(n *html.Node) bool {
- return a(n) && b(n)
- }
-}
-
-// unionSelector returns a selector that matches elements that match
-// either a or b.
-func unionSelector(a, b Selector) Selector {
- return func(n *html.Node) bool {
- return a(n) || b(n)
- }
-}
-
-// negatedSelector returns a selector that matches elements that do not match a.
-func negatedSelector(a Selector) Selector {
- return func(n *html.Node) bool {
- if n.Type != html.ElementNode {
- return false
- }
- return !a(n)
- }
-}
-
-// 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()
-}
-
-// textSubstrSelector returns a selector that matches nodes that
-// contain the given text.
-func textSubstrSelector(val string) Selector {
- return func(n *html.Node) bool {
- text := strings.ToLower(nodeText(n))
- return strings.Contains(text, val)
- }
-}
-
-// ownTextSubstrSelector returns a selector that matches nodes that
-// directly contain the given text
-func ownTextSubstrSelector(val string) Selector {
- return func(n *html.Node) bool {
- text := strings.ToLower(nodeOwnText(n))
- return strings.Contains(text, val)
- }
-}
-
-// textRegexSelector returns a selector that matches nodes whose text matches
-// the specified regular expression
-func textRegexSelector(rx *regexp.Regexp) Selector {
- return func(n *html.Node) bool {
- return rx.MatchString(nodeText(n))
- }
-}
-
-// ownTextRegexSelector returns a selector that matches nodes whose text
-// directly matches the specified regular expression
-func ownTextRegexSelector(rx *regexp.Regexp) Selector {
- return func(n *html.Node) bool {
- return rx.MatchString(nodeOwnText(n))
- }
-}
-
-// hasChildSelector returns a selector that matches elements
-// with a child that matches a.
-func hasChildSelector(a Selector) Selector {
- return func(n *html.Node) bool {
- if n.Type != html.ElementNode {
- return false
- }
- return hasChildMatch(n, a)
- }
-}
-
-// hasDescendantSelector returns a selector that matches elements
-// with any descendant that matches a.
-func hasDescendantSelector(a Selector) Selector {
- return func(n *html.Node) bool {
- if n.Type != html.ElementNode {
- return false
- }
- return hasDescendantMatch(n, a)
- }
-}
-
-// nthChildSelector returns a selector that implements :nth-child(an+b).
-// If last is true, implements :nth-last-child instead.
-// If ofType is true, implements :nth-of-type instead.
-func nthChildSelector(a, b int, last, ofType bool) Selector {
- return func(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
- }
-}
-
-// simpleNthChildSelector returns a selector that implements :nth-child(b).
-// If ofType is true, implements :nth-of-type instead.
-func simpleNthChildSelector(b int, ofType bool) Selector {
- return func(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
- }
-}
-
-// simpleNthLastChildSelector returns a selector that implements
-// :nth-last-child(b). If ofType is true, implements :nth-last-of-type
-// instead.
-func simpleNthLastChildSelector(b int, ofType bool) Selector {
- return func(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
- }
-}
-
-// onlyChildSelector returns a selector that implements :only-child.
-// If ofType is true, it implements :only-of-type instead.
-func onlyChildSelector(ofType bool) Selector {
- return func(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 count > 1 {
- return false
- }
- }
-
- return count == 1
- }
-}
-
-// inputSelector is a Selector that matches input, select, textarea and button elements.
-func inputSelector(n *html.Node) bool {
- return n.Type == html.ElementNode && (n.Data == "input" || n.Data == "select" || n.Data == "textarea" || n.Data == "button")
-}
-
-// emptyElementSelector is a Selector that matches empty elements.
-func emptyElementSelector(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
-}
-
-// descendantSelector returns a Selector that matches an element if
-// it matches d and has an ancestor that matches a.
-func descendantSelector(a, d Selector) Selector {
- return func(n *html.Node) bool {
- if !d(n) {
- return false
- }
-
- for p := n.Parent; p != nil; p = p.Parent {
- if a(p) {
- return true
- }
- }
-
- return false
- }
-}
-
-// childSelector returns a Selector that matches an element if
-// it matches d and its parent matches a.
-func childSelector(a, d Selector) Selector {
- return func(n *html.Node) bool {
- return d(n) && n.Parent != nil && a(n.Parent)
- }
-}
-
-// siblingSelector returns a Selector that matches an element
-// if it matches s2 and in is preceded by an element that matches s1.
-// If adjacent is true, the sibling must be immediately before the element.
-func siblingSelector(s1, s2 Selector, adjacent bool) Selector {
- return func(n *html.Node) bool {
- if !s2(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(n)
- }
- return false
- }
-
- // Walk backwards looking for element that matches s1
- for c := n.PrevSibling; c != nil; c = c.PrevSibling {
- if s1(c) {
- return true
- }
- }
-
- return false
- }
-}
-
-// rootSelector implements :root
-func rootSelector(n *html.Node) bool {
- if n.Type != html.ElementNode {
- return false
- }
- if n.Parent == nil {
- return false
- }
- return n.Parent.Type == html.DocumentNode
-}
diff --git a/vendor/github.com/docopt/docopt-go/.gitignore b/vendor/github.com/docopt/docopt-go/.gitignore
deleted file mode 100644
index 49ad16c6..00000000
--- a/vendor/github.com/docopt/docopt-go/.gitignore
+++ /dev/null
@@ -1,25 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-
-# coverage droppings
-profile.cov
diff --git a/vendor/github.com/docopt/docopt-go/.travis.yml b/vendor/github.com/docopt/docopt-go/.travis.yml
deleted file mode 100644
index db820dc3..00000000
--- a/vendor/github.com/docopt/docopt-go/.travis.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-# Travis CI (http://travis-ci.org/) is a continuous integration
-# service for open source projects. This file configures it
-# to run unit tests for docopt-go.
-
-language: go
-
-go:
- - 1.4
- - 1.5
- - 1.6
- - 1.7
- - 1.8
- - 1.9
- - tip
-
-matrix:
- fast_finish: true
-
-before_install:
- - go get golang.org/x/tools/cmd/cover
- - go get github.com/mattn/goveralls
-
-install:
- - go get -d -v ./... && go build -v ./...
-
-script:
- - go vet -x ./...
- - go test -v ./...
- - go test -covermode=count -coverprofile=profile.cov .
-
-after_script:
- - $HOME/gopath/bin/goveralls -coverprofile=profile.cov -service=travis-ci
diff --git a/vendor/github.com/docopt/docopt-go/LICENSE b/vendor/github.com/docopt/docopt-go/LICENSE
deleted file mode 100644
index 5e51f73e..00000000
--- a/vendor/github.com/docopt/docopt-go/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Keith Batten
-Copyright (c) 2016 David Irvine
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/docopt/docopt-go/README.md b/vendor/github.com/docopt/docopt-go/README.md
deleted file mode 100644
index d03f8da5..00000000
--- a/vendor/github.com/docopt/docopt-go/README.md
+++ /dev/null
@@ -1,116 +0,0 @@
-docopt-go
-=========
-
-[](https://travis-ci.org/docopt/docopt.go)
-[](https://coveralls.io/github/docopt/docopt.go)
-[](https://godoc.org/github.com/docopt/docopt.go)
-
-An implementation of [docopt](http://docopt.org/) in the [Go](http://golang.org/) programming language.
-
-**docopt** helps you create *beautiful* command-line interfaces easily:
-
-```go
-package main
-
-import (
- "fmt"
- "github.com/docopt/docopt-go"
-)
-
-func main() {
- usage := `Naval Fate.
-
-Usage:
- naval_fate ship new block.
- if d != "" && d[0] == '\r' {
- d = d[1:]
- }
- if d != "" && d[0] == '\n' {
- d = d[1:]
- }
- }
- }
- d = strings.Replace(d, "\x00", "", -1)
- if d == "" {
- return true
- }
- p.reconstructActiveFormattingElements()
- p.addText(d)
- if p.framesetOK && strings.TrimLeft(d, whitespace) != "" {
- // There were non-whitespace characters inserted.
- p.framesetOK = false
- }
- case StartTagToken:
- switch p.tok.DataAtom {
- case a.Html:
- if p.oe.contains(a.Template) {
- return true
- }
- copyAttributes(p.oe[0], p.tok)
- case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
- return inHeadIM(p)
- case a.Body:
- if p.oe.contains(a.Template) {
- return true
- }
- if len(p.oe) >= 2 {
- body := p.oe[1]
- if body.Type == ElementNode && body.DataAtom == a.Body {
- p.framesetOK = false
- copyAttributes(body, p.tok)
- }
- }
- case a.Frameset:
- if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {
- // Ignore the token.
- return true
- }
- body := p.oe[1]
- if body.Parent != nil {
- body.Parent.RemoveChild(body)
- }
- p.oe = p.oe[:1]
- p.addElement()
- p.im = inFramesetIM
- return true
- case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
- p.popUntil(buttonScope, a.P)
- p.addElement()
- case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
- p.popUntil(buttonScope, a.P)
- switch n := p.top(); n.DataAtom {
- case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
- p.oe.pop()
- }
- p.addElement()
- case a.Pre, a.Listing:
- p.popUntil(buttonScope, a.P)
- p.addElement()
- // The newline, if any, will be dealt with by the TextToken case.
- p.framesetOK = false
- case a.Form:
- if p.form != nil && !p.oe.contains(a.Template) {
- // Ignore the token
- return true
- }
- p.popUntil(buttonScope, a.P)
- p.addElement()
- if !p.oe.contains(a.Template) {
- p.form = p.top()
- }
- case a.Li:
- p.framesetOK = false
- for i := len(p.oe) - 1; i >= 0; i-- {
- node := p.oe[i]
- switch node.DataAtom {
- case a.Li:
- p.oe = p.oe[:i]
- case a.Address, a.Div, a.P:
- continue
- default:
- if !isSpecialElement(node) {
- continue
- }
- }
- break
- }
- p.popUntil(buttonScope, a.P)
- p.addElement()
- case a.Dd, a.Dt:
- p.framesetOK = false
- for i := len(p.oe) - 1; i >= 0; i-- {
- node := p.oe[i]
- switch node.DataAtom {
- case a.Dd, a.Dt:
- p.oe = p.oe[:i]
- case a.Address, a.Div, a.P:
- continue
- default:
- if !isSpecialElement(node) {
- continue
- }
- }
- break
- }
- p.popUntil(buttonScope, a.P)
- p.addElement()
- case a.Plaintext:
- p.popUntil(buttonScope, a.P)
- p.addElement()
- case a.Button:
- p.popUntil(defaultScope, a.Button)
- p.reconstructActiveFormattingElements()
- p.addElement()
- p.framesetOK = false
- case a.A:
- for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
- if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {
- p.inBodyEndTagFormatting(a.A, "a")
- p.oe.remove(n)
- p.afe.remove(n)
- break
- }
- }
- p.reconstructActiveFormattingElements()
- p.addFormattingElement()
- case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
- p.reconstructActiveFormattingElements()
- p.addFormattingElement()
- case a.Nobr:
- p.reconstructActiveFormattingElements()
- if p.elementInScope(defaultScope, a.Nobr) {
- p.inBodyEndTagFormatting(a.Nobr, "nobr")
- p.reconstructActiveFormattingElements()
- }
- p.addFormattingElement()
- case a.Applet, a.Marquee, a.Object:
- p.reconstructActiveFormattingElements()
- p.addElement()
- p.afe = append(p.afe, &scopeMarker)
- p.framesetOK = false
- case a.Table:
- if !p.quirks {
- p.popUntil(buttonScope, a.P)
- }
- p.addElement()
- p.framesetOK = false
- p.im = inTableIM
- return true
- case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
- p.reconstructActiveFormattingElements()
- p.addElement()
- p.oe.pop()
- p.acknowledgeSelfClosingTag()
- if p.tok.DataAtom == a.Input {
- for _, t := range p.tok.Attr {
- if t.Key == "type" {
- if strings.ToLower(t.Val) == "hidden" {
- // Skip setting framesetOK = false
- return true
- }
- }
- }
- }
- p.framesetOK = false
- case a.Param, a.Source, a.Track:
- p.addElement()
- p.oe.pop()
- p.acknowledgeSelfClosingTag()
- case a.Hr:
- p.popUntil(buttonScope, a.P)
- p.addElement()
- p.oe.pop()
- p.acknowledgeSelfClosingTag()
- p.framesetOK = false
- case a.Image:
- p.tok.DataAtom = a.Img
- p.tok.Data = a.Img.String()
- return false
- case a.Isindex:
- if p.form != nil {
- // Ignore the token.
- return true
- }
- action := ""
- prompt := "This is a searchable index. Enter search keywords: "
- attr := []Attribute{{Key: "name", Val: "isindex"}}
- for _, t := range p.tok.Attr {
- switch t.Key {
- case "action":
- action = t.Val
- case "name":
- // Ignore the attribute.
- case "prompt":
- prompt = t.Val
- default:
- attr = append(attr, t)
- }
- }
- p.acknowledgeSelfClosingTag()
- p.popUntil(buttonScope, a.P)
- p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
- if p.form == nil {
- // NOTE: The 'isindex' element has been removed,
- // and the 'template' element has not been designed to be
- // collaborative with the index element.
- //
- // Ignore the token.
- return true
- }
- if action != "" {
- p.form.Attr = []Attribute{{Key: "action", Val: action}}
- }
- p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
- p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
- p.addText(prompt)
- p.addChild(&Node{
- Type: ElementNode,
- DataAtom: a.Input,
- Data: a.Input.String(),
- Attr: attr,
- })
- p.oe.pop()
- p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
- p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
- p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
- case a.Textarea:
- p.addElement()
- p.setOriginalIM()
- p.framesetOK = false
- p.im = textIM
- case a.Xmp:
- p.popUntil(buttonScope, a.P)
- p.reconstructActiveFormattingElements()
- p.framesetOK = false
- p.addElement()
- p.setOriginalIM()
- p.im = textIM
- case a.Iframe:
- p.framesetOK = false
- p.addElement()
- p.setOriginalIM()
- p.im = textIM
- case a.Noembed, a.Noscript:
- p.addElement()
- p.setOriginalIM()
- p.im = textIM
- case a.Select:
- p.reconstructActiveFormattingElements()
- p.addElement()
- p.framesetOK = false
- p.im = inSelectIM
- return true
- case a.Optgroup, a.Option:
- if p.top().DataAtom == a.Option {
- p.oe.pop()
- }
- p.reconstructActiveFormattingElements()
- p.addElement()
- case a.Rb, a.Rtc:
- if p.elementInScope(defaultScope, a.Ruby) {
- p.generateImpliedEndTags()
- }
- p.addElement()
- case a.Rp, a.Rt:
- if p.elementInScope(defaultScope, a.Ruby) {
- p.generateImpliedEndTags("rtc")
- }
- p.addElement()
- case a.Math, a.Svg:
- p.reconstructActiveFormattingElements()
- if p.tok.DataAtom == a.Math {
- adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
- } else {
- adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
- }
- adjustForeignAttributes(p.tok.Attr)
- p.addElement()
- p.top().Namespace = p.tok.Data
- if p.hasSelfClosingToken {
- p.oe.pop()
- p.acknowledgeSelfClosingTag()
- }
- return true
- case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
- // Ignore the token.
- default:
- p.reconstructActiveFormattingElements()
- p.addElement()
- }
- case EndTagToken:
- switch p.tok.DataAtom {
- case a.Body:
- if p.elementInScope(defaultScope, a.Body) {
- p.im = afterBodyIM
- }
- case a.Html:
- if p.elementInScope(defaultScope, a.Body) {
- p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
- return false
- }
- return true
- case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
- p.popUntil(defaultScope, p.tok.DataAtom)
- case a.Form:
- if p.oe.contains(a.Template) {
- i := p.indexOfElementInScope(defaultScope, a.Form)
- if i == -1 {
- // Ignore the token.
- return true
- }
- p.generateImpliedEndTags()
- if p.oe[i].DataAtom != a.Form {
- // Ignore the token.
- return true
- }
- p.popUntil(defaultScope, a.Form)
- } else {
- node := p.form
- p.form = nil
- i := p.indexOfElementInScope(defaultScope, a.Form)
- if node == nil || i == -1 || p.oe[i] != node {
- // Ignore the token.
- return true
- }
- p.generateImpliedEndTags()
- p.oe.remove(node)
- }
- case a.P:
- if !p.elementInScope(buttonScope, a.P) {
- p.parseImpliedToken(StartTagToken, a.P, a.P.String())
- }
- p.popUntil(buttonScope, a.P)
- case a.Li:
- p.popUntil(listItemScope, a.Li)
- case a.Dd, a.Dt:
- p.popUntil(defaultScope, p.tok.DataAtom)
- case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
- p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)
- case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
- p.inBodyEndTagFormatting(p.tok.DataAtom, p.tok.Data)
- case a.Applet, a.Marquee, a.Object:
- if p.popUntil(defaultScope, p.tok.DataAtom) {
- p.clearActiveFormattingElements()
- }
- case a.Br:
- p.tok.Type = StartTagToken
- return false
- case a.Template:
- return inHeadIM(p)
- default:
- p.inBodyEndTagOther(p.tok.DataAtom, p.tok.Data)
- }
- case CommentToken:
- p.addChild(&Node{
- Type: CommentNode,
- Data: p.tok.Data,
- })
- case ErrorToken:
- // TODO: remove this divergence from the HTML5 spec.
- if len(p.templateStack) > 0 {
- p.im = inTemplateIM
- return false
- } else {
- for _, e := range p.oe {
- switch e.DataAtom {
- case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,
- a.Thead, a.Tr, a.Body, a.Html:
- default:
- return true
- }
- }
- }
- }
-
- return true
-}
-
-func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {
- // This is the "adoption agency" algorithm, described at
- // https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency
-
- // TODO: this is a fairly literal line-by-line translation of that algorithm.
- // Once the code successfully parses the comprehensive test suite, we should
- // refactor this code to be more idiomatic.
-
- // Steps 1-4. The outer loop.
- for i := 0; i < 8; i++ {
- // Step 5. Find the formatting element.
- var formattingElement *Node
- for j := len(p.afe) - 1; j >= 0; j-- {
- if p.afe[j].Type == scopeMarkerNode {
- break
- }
- if p.afe[j].DataAtom == tagAtom {
- formattingElement = p.afe[j]
- break
- }
- }
- if formattingElement == nil {
- p.inBodyEndTagOther(tagAtom, tagName)
- return
- }
- feIndex := p.oe.index(formattingElement)
- if feIndex == -1 {
- p.afe.remove(formattingElement)
- return
- }
- if !p.elementInScope(defaultScope, tagAtom) {
- // Ignore the tag.
- return
- }
-
- // Steps 9-10. Find the furthest block.
- var furthestBlock *Node
- for _, e := range p.oe[feIndex:] {
- if isSpecialElement(e) {
- furthestBlock = e
- break
- }
- }
- if furthestBlock == nil {
- e := p.oe.pop()
- for e != formattingElement {
- e = p.oe.pop()
- }
- p.afe.remove(e)
- return
- }
-
- // Steps 11-12. Find the common ancestor and bookmark node.
- commonAncestor := p.oe[feIndex-1]
- bookmark := p.afe.index(formattingElement)
-
- // Step 13. The inner loop. Find the lastNode to reparent.
- lastNode := furthestBlock
- node := furthestBlock
- x := p.oe.index(node)
- // Steps 13.1-13.2
- for j := 0; j < 3; j++ {
- // Step 13.3.
- x--
- node = p.oe[x]
- // Step 13.4 - 13.5.
- if p.afe.index(node) == -1 {
- p.oe.remove(node)
- continue
- }
- // Step 13.6.
- if node == formattingElement {
- break
- }
- // Step 13.7.
- clone := node.clone()
- p.afe[p.afe.index(node)] = clone
- p.oe[p.oe.index(node)] = clone
- node = clone
- // Step 13.8.
- if lastNode == furthestBlock {
- bookmark = p.afe.index(node) + 1
- }
- // Step 13.9.
- if lastNode.Parent != nil {
- lastNode.Parent.RemoveChild(lastNode)
- }
- node.AppendChild(lastNode)
- // Step 13.10.
- lastNode = node
- }
-
- // Step 14. Reparent lastNode to the common ancestor,
- // or for misnested table nodes, to the foster parent.
- if lastNode.Parent != nil {
- lastNode.Parent.RemoveChild(lastNode)
- }
- switch commonAncestor.DataAtom {
- case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
- p.fosterParent(lastNode)
- default:
- commonAncestor.AppendChild(lastNode)
- }
-
- // Steps 15-17. Reparent nodes from the furthest block's children
- // to a clone of the formatting element.
- clone := formattingElement.clone()
- reparentChildren(clone, furthestBlock)
- furthestBlock.AppendChild(clone)
-
- // Step 18. Fix up the list of active formatting elements.
- if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
- // Move the bookmark with the rest of the list.
- bookmark--
- }
- p.afe.remove(formattingElement)
- p.afe.insert(bookmark, clone)
-
- // Step 19. Fix up the stack of open elements.
- p.oe.remove(formattingElement)
- p.oe.insert(p.oe.index(furthestBlock)+1, clone)
- }
-}
-
-// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
-// "Any other end tag" handling from 12.2.6.5 The rules for parsing tokens in foreign content
-// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
-func (p *parser) inBodyEndTagOther(tagAtom a.Atom, tagName string) {
- for i := len(p.oe) - 1; i >= 0; i-- {
- // Two element nodes have the same tag if they have the same Data (a
- // string-typed field). As an optimization, for common HTML tags, each
- // Data string is assigned a unique, non-zero DataAtom (a uint32-typed
- // field), since integer comparison is faster than string comparison.
- // Uncommon (custom) tags get a zero DataAtom.
- //
- // The if condition here is equivalent to (p.oe[i].Data == tagName).
- if (p.oe[i].DataAtom == tagAtom) &&
- ((tagAtom != 0) || (p.oe[i].Data == tagName)) {
- p.oe = p.oe[:i]
- break
- }
- if isSpecialElement(p.oe[i]) {
- break
- }
- }
-}
-
-// Section 12.2.6.4.8.
-func textIM(p *parser) bool {
- switch p.tok.Type {
- case ErrorToken:
- p.oe.pop()
- case TextToken:
- d := p.tok.Data
- if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {
- // Ignore a newline at the start of a