Update server dependencies
This commit is contained in:
parent
c704ebb042
commit
1794e2680a
369 changed files with 23554 additions and 6306 deletions
2
vendor/github.com/tdewolff/minify/v2/.goreleaser.yml
generated
vendored
2
vendor/github.com/tdewolff/minify/v2/.goreleaser.yml
generated
vendored
|
@ -1,7 +1,7 @@
|
|||
builds:
|
||||
- binary: minify
|
||||
main: ./cmd/minify/
|
||||
ldflags: -s -w -X main.Version={{.Version}} -X main.Commit={{.Commit}} -X main.Date={{.Date}}
|
||||
ldflags: -s -w -X main.Version={{.Version}}
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
- GO111MODULE=on
|
||||
|
|
8
vendor/github.com/tdewolff/minify/v2/.travis.yml
generated
vendored
8
vendor/github.com/tdewolff/minify/v2/.travis.yml
generated
vendored
|
@ -1,6 +1,10 @@
|
|||
language: go
|
||||
go:
|
||||
- 1.13.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
script:
|
||||
- go test -v -covermode=count -coverprofile=profile.cov . ./css ./html ./js ./json ./svg ./xml
|
||||
- goveralls -v -coverprofile=profile.cov -service travis-ci -repotoken $COVERALLS_TOKEN
|
||||
- go test -covermode=count -coverprofile=profile.cov . ./css ./html ./js ./json ./svg ./xml
|
||||
- goveralls -coverprofile=profile.cov -service travis-ci
|
||||
|
|
62
vendor/github.com/tdewolff/minify/v2/README.md
generated
vendored
62
vendor/github.com/tdewolff/minify/v2/README.md
generated
vendored
|
@ -1,20 +1,14 @@
|
|||
# Minify <a name="minify"></a> [](https://travis-ci.org/tdewolff/minify) [](http://godoc.org/github.com/tdewolff/minify) [](https://coveralls.io/github/tdewolff/minify?branch=master) [](https://gitter.im/tdewolff/minify?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
***BE AWARE: YOU NEED GO 1.9.7+, 1.10.3+, 1.11 to run the latest release!!!***
|
||||
|
||||
If you cannot upgrade Go, please pin to **minify@v2.3.6** and **parse@v2.3.4**
|
||||
|
||||
---
|
||||
# Minify <a name="minify"></a> [](https://travis-ci.org/tdewolff/minify) [](http://godoc.org/github.com/tdewolff/minify) [](https://coveralls.io/github/tdewolff/minify?branch=master)
|
||||
|
||||
**[Online demo](https://go.tacodewolff.nl/minify) if you need to minify files *now*.**
|
||||
|
||||
**[Command line tool](https://github.com/tdewolff/minify/tree/master/cmd/minify) that minifies concurrently and supports watching file changes.**
|
||||
|
||||
**[All releases](https://github.com/tdewolff/minify/releases) for various platforms.**
|
||||
**[Releases](https://github.com/tdewolff/minify/releases) of CLI for various platforms.** See [CLI](https://github.com/tdewolff/minify/tree/master/cmd/minify) for more installation instructions.
|
||||
|
||||
---
|
||||
|
||||
*Did you know that the shortest valid piece of HTML5 is `<!doctype html><html lang=en><title>x</title>`? See for yourself at the [W3C Validator](http://validator.w3.org/)!*
|
||||
*Did you know that the shortest valid piece of HTML5 is `<!doctype html><title>x</title>`? See for yourself at the [W3C Validator](http://validator.w3.org/)!*
|
||||
|
||||
Minify is a minifier package written in [Go][1]. It provides HTML5, CSS3, JS, JSON, SVG and XML minifiers and an interface to implement any other minifier. Minification is the process of removing bytes from a file (such as whitespace) without changing its output and therefore shrinking its size and speeding up transmission over the internet and possibly parsing. The implemented minifiers are designed for high performance.
|
||||
|
||||
|
@ -47,6 +41,10 @@ The core functionality associates mimetypes with minification functions, allowin
|
|||
- [Mediatypes](#mediatypes)
|
||||
- [Examples](#examples)
|
||||
- [Common minifiers](#common-minifiers)
|
||||
- [External minifiers](#external-minifiers)
|
||||
- [Closure Compiler](#closure-compiler)
|
||||
- [UglifyJS](#uglifyjs)
|
||||
- [esbuild](#esbuild)
|
||||
- [Custom minifier](#custom-minifier-example)
|
||||
- [ResponseWriter](#responsewriter)
|
||||
- [Templates](#templates)
|
||||
|
@ -76,11 +74,7 @@ Minifiers or bindings to minifiers exist in almost all programming languages. So
|
|||
This minifier proves to be that fast and extensive minifier that can handle HTML and any other filetype it may contain (CSS, JS, ...). It is usually orders of magnitude faster than existing minifiers.
|
||||
|
||||
## Installation
|
||||
Run the following command
|
||||
|
||||
go get -u github.com/tdewolff/minify/v2
|
||||
|
||||
or add the following imports and run the project with `go get`
|
||||
With modules enabled (`GO111MODULES=auto` or `GO111MODULES=on`), add the following imports and run the project with `go get`
|
||||
``` go
|
||||
import (
|
||||
"github.com/tdewolff/minify/v2"
|
||||
|
@ -93,6 +87,8 @@ import (
|
|||
)
|
||||
```
|
||||
|
||||
See [CLI tool](https://github.com/tdewolff/minify/tree/master/cmd/minify) for installation instructions of the binary.
|
||||
|
||||
## API stability
|
||||
There is no guarantee for absolute stability, but I take issues and bugs seriously and don't take API changes lightly. The library will be maintained in a compatible way unless vital bugs prevent me from doing so. There has been one API change after v1 which added options support and I took the opportunity to push through some more API clean up as well. There are no plans whatsoever for future API changes.
|
||||
|
||||
|
@ -175,6 +171,7 @@ Options:
|
|||
- `KeepDefaultAttrVals` preserve default attribute values such as `<script type="application/javascript">`
|
||||
- `KeepDocumentTags` preserve `html`, `head` and `body` tags
|
||||
- `KeepEndTags` preserve all end tags
|
||||
- `KeepQuotes` preserve quotes around attribute values
|
||||
- `KeepWhitespace` preserve whitespace between inline tags but still collapse multiple whitespace characters into one
|
||||
|
||||
After recent benchmarking and profiling it became really fast and minifies pages in the 10ms range, making it viable for on-the-fly minification.
|
||||
|
@ -225,8 +222,8 @@ There are a couple of comparison tables online, such as [CSS Minifier Comparison
|
|||
|
||||
Options:
|
||||
|
||||
- `Decimals` number of decimals to preserve for numbers, `-1` means no trimming
|
||||
- `KeepCSS2` prohibits using CSS3 syntax (such as exponents in numbers, or `rgba(` → `rgb(`), might be incomplete
|
||||
- `Precision` number of significant digits to preserve for numbers, `0` means no trimming
|
||||
|
||||
## JS
|
||||
|
||||
|
@ -257,7 +254,6 @@ The SVG minifier uses these minifications:
|
|||
- minify colors
|
||||
- shorten lengths and numbers and remove default `px` unit
|
||||
- shorten `path` data
|
||||
- convert `rect`, `line`, `polygon`, `polyline` to `path`
|
||||
- use relative or absolute positions in path data whichever is shorter
|
||||
|
||||
TODO:
|
||||
|
@ -266,7 +262,7 @@ TODO:
|
|||
|
||||
Options:
|
||||
|
||||
- `Decimals` number of decimals to preserve for numbers, `-1` means no trimming
|
||||
- `Precision` number of significant digits to preserve for numbers, `0` means no trimming
|
||||
|
||||
## XML
|
||||
|
||||
|
@ -432,15 +428,39 @@ func main() {
|
|||
m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)
|
||||
m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)
|
||||
|
||||
// Or use the following for better minification of JS but lower speed:
|
||||
// m.AddCmdRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"), exec.Command("java", "-jar", "build/compiler.jar"))
|
||||
|
||||
if err := m.Minify("text/html", os.Stdout, os.Stdin); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### External minifiers
|
||||
Below are some examples of using common external minifiers.
|
||||
|
||||
#### Closure Compiler
|
||||
See [Closure Compiler Application](https://developers.google.com/closure/compiler/docs/gettingstarted_app). Not tested.
|
||||
|
||||
``` go
|
||||
m.AddCmdRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"),
|
||||
exec.Command("java", "-jar", "build/compiler.jar"))
|
||||
```
|
||||
|
||||
### UglifyJS
|
||||
See [UglifyJS](https://github.com/mishoo/UglifyJS2).
|
||||
|
||||
``` go
|
||||
m.AddCmdRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"),
|
||||
exec.Command("uglifyjs"))
|
||||
```
|
||||
|
||||
### esbuild
|
||||
See [esbuild](https://github.com/evanw/esbuild).
|
||||
|
||||
``` go
|
||||
m.AddCmdRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"),
|
||||
exec.Command("esbuild", "$in.js", "--minify", "--outfile=$out.js"))
|
||||
```
|
||||
|
||||
### <a name="custom-minifier-example"></a> Custom minifier
|
||||
Custom minifier showing an example that implements the minifier function interface. Within a custom minifier, it is possible to call any minifier function (through `m minify.Minifier`) recursively when dealing with embedded resources.
|
||||
``` go
|
||||
|
@ -588,7 +608,7 @@ func compileTemplates(filenames ...string) (*template.Template, error) {
|
|||
Example usage:
|
||||
|
||||
``` go
|
||||
templates := template.MustCompile(compileTemplates("view.html", "home.html"))
|
||||
templates := template.Must(compileTemplates("view.html", "home.html"))
|
||||
```
|
||||
|
||||
## License
|
||||
|
|
363
vendor/github.com/tdewolff/minify/v2/common.go
generated
vendored
363
vendor/github.com/tdewolff/minify/v2/common.go
generated
vendored
|
@ -1,9 +1,7 @@
|
|||
package minify // import "github.com/tdewolff/minify"
|
||||
package minify
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"net/url"
|
||||
|
||||
"github.com/tdewolff/parse/v2"
|
||||
"github.com/tdewolff/parse/v2/strconv"
|
||||
|
@ -38,50 +36,57 @@ func Mediatype(b []byte) []byte {
|
|||
|
||||
// DataURI minifies a data URI and calls a minifier by the specified mediatype. Specifications: https://www.ietf.org/rfc/rfc2397.txt.
|
||||
func DataURI(m *M, dataURI []byte) []byte {
|
||||
if mediatype, data, err := parse.DataURI(dataURI); err == nil {
|
||||
dataURI, _ = m.Bytes(string(mediatype), data)
|
||||
base64Len := len(";base64") + base64.StdEncoding.EncodedLen(len(dataURI))
|
||||
asciiLen := len(dataURI)
|
||||
for _, c := range dataURI {
|
||||
if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' || c == '_' || c == '.' || c == '~' || c == ' ' {
|
||||
asciiLen++
|
||||
} else {
|
||||
asciiLen += 2
|
||||
}
|
||||
if asciiLen > base64Len {
|
||||
break
|
||||
}
|
||||
origData := parse.Copy(dataURI)
|
||||
mediatype, data, err := parse.DataURI(dataURI)
|
||||
if err != nil {
|
||||
return dataURI
|
||||
}
|
||||
|
||||
data, _ = m.Bytes(string(mediatype), data)
|
||||
base64Len := len(";base64") + base64.StdEncoding.EncodedLen(len(data))
|
||||
asciiLen := len(data)
|
||||
for _, c := range data {
|
||||
if parse.URLEncodingTable[c] {
|
||||
asciiLen += 2
|
||||
}
|
||||
if asciiLen > base64Len {
|
||||
encoded := make([]byte, base64Len-len(";base64"))
|
||||
base64.StdEncoding.Encode(encoded, dataURI)
|
||||
dataURI = encoded
|
||||
mediatype = append(mediatype, []byte(";base64")...)
|
||||
} else {
|
||||
dataURI = []byte(url.QueryEscape(string(dataURI)))
|
||||
dataURI = bytes.Replace(dataURI, []byte("\""), []byte("\\\""), -1)
|
||||
break
|
||||
}
|
||||
if len("text/plain") <= len(mediatype) && parse.EqualFold(mediatype[:len("text/plain")], []byte("text/plain")) {
|
||||
mediatype = mediatype[len("text/plain"):]
|
||||
}
|
||||
for i := 0; i+len(";charset=us-ascii") <= len(mediatype); i++ {
|
||||
// must start with semicolon and be followed by end of mediatype or semicolon
|
||||
if mediatype[i] == ';' && parse.EqualFold(mediatype[i+1:i+len(";charset=us-ascii")], []byte("charset=us-ascii")) && (i+len(";charset=us-ascii") >= len(mediatype) || mediatype[i+len(";charset=us-ascii")] == ';') {
|
||||
mediatype = append(mediatype[:i], mediatype[i+len(";charset=us-ascii"):]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
dataURI = append(append(append([]byte("data:"), mediatype...), ','), dataURI...)
|
||||
}
|
||||
return dataURI
|
||||
if len(origData) < base64Len && len(origData) < asciiLen {
|
||||
return origData
|
||||
}
|
||||
if base64Len < asciiLen {
|
||||
encoded := make([]byte, base64Len-len(";base64"))
|
||||
base64.StdEncoding.Encode(encoded, data)
|
||||
data = encoded
|
||||
mediatype = append(mediatype, []byte(";base64")...)
|
||||
} else {
|
||||
data = parse.EncodeURL(data, parse.URLEncodingTable)
|
||||
}
|
||||
if len("text/plain") <= len(mediatype) && parse.EqualFold(mediatype[:len("text/plain")], []byte("text/plain")) {
|
||||
mediatype = mediatype[len("text/plain"):]
|
||||
}
|
||||
for i := 0; i+len(";charset=us-ascii") <= len(mediatype); i++ {
|
||||
// must start with semicolon and be followed by end of mediatype or semicolon
|
||||
if mediatype[i] == ';' && parse.EqualFold(mediatype[i+1:i+len(";charset=us-ascii")], []byte("charset=us-ascii")) && (i+len(";charset=us-ascii") >= len(mediatype) || mediatype[i+len(";charset=us-ascii")] == ';') {
|
||||
mediatype = append(mediatype[:i], mediatype[i+len(";charset=us-ascii"):]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
return append(append(append([]byte("data:"), mediatype...), ','), data...)
|
||||
}
|
||||
|
||||
const MaxInt = int(^uint(0) >> 1)
|
||||
const MinInt = -MaxInt - 1
|
||||
|
||||
// Decimal minifies a given byte slice containing a number (see parse.Number) and removes superfluous characters.
|
||||
// It does not parse or output exponents.
|
||||
// It does not parse or output exponents. prec is the number of significant digits. When prec is zero it will keep all digits. Only digits after the dot can be removed to reach the number of significant digits. Very large number may thus have more significant digits.
|
||||
func Decimal(num []byte, prec int) []byte {
|
||||
if len(num) <= 1 {
|
||||
return num
|
||||
}
|
||||
|
||||
// omit first + and register mantissa start and end, whether it's negative and the exponent
|
||||
neg := false
|
||||
start := 0
|
||||
|
@ -109,7 +114,7 @@ func Decimal(num []byte, prec int) []byte {
|
|||
}
|
||||
// trim trailing zeros
|
||||
i := end - 1
|
||||
for ; i > dot; i-- {
|
||||
for ; dot < i; i-- {
|
||||
if num[i] != '0' {
|
||||
end = i + 1
|
||||
break
|
||||
|
@ -126,51 +131,48 @@ func Decimal(num []byte, prec int) []byte {
|
|||
}
|
||||
|
||||
// apply precision
|
||||
if prec > -1 && dot+1+prec < end {
|
||||
end = dot + 1 + prec
|
||||
inc := num[end] >= '5'
|
||||
if inc || num[end-1] == '0' {
|
||||
if 0 < prec && dot <= start+prec {
|
||||
precEnd := start + prec + 1 // include dot
|
||||
if dot == start { // for numbers like .012
|
||||
digit := start + 1
|
||||
for digit < end && num[digit] == '0' {
|
||||
digit++
|
||||
}
|
||||
precEnd = digit + prec
|
||||
}
|
||||
if precEnd < end {
|
||||
end = precEnd
|
||||
|
||||
// process either an increase from a lesser significant decimal (>= 5)
|
||||
// or remove trailing zeros after the dot, or both
|
||||
for i := end - 1; i > start; i-- {
|
||||
i := end - 1
|
||||
inc := '5' <= num[end]
|
||||
for ; start < i; i-- {
|
||||
if i == dot {
|
||||
end--
|
||||
} else if inc {
|
||||
if num[i] == '9' {
|
||||
if i > dot {
|
||||
end--
|
||||
} else {
|
||||
num[i] = '0'
|
||||
break
|
||||
}
|
||||
} else {
|
||||
num[i]++
|
||||
inc = false
|
||||
break
|
||||
}
|
||||
} else if i > dot && num[i] == '0' {
|
||||
end--
|
||||
} else {
|
||||
// no-op
|
||||
} else if inc && num[i] != '9' {
|
||||
num[i]++
|
||||
inc = false
|
||||
break
|
||||
} else if inc && i < dot { // end inc for integer
|
||||
num[i] = '0'
|
||||
} else if !inc && (i < dot || num[i] != '0') {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if dot == start && end == start+1 {
|
||||
if inc {
|
||||
num[start] = '1'
|
||||
if i < dot {
|
||||
end = dot
|
||||
} else {
|
||||
num[start] = '0'
|
||||
}
|
||||
} else {
|
||||
if dot+1 == end {
|
||||
end--
|
||||
end = i + 1
|
||||
}
|
||||
|
||||
if inc {
|
||||
if num[start] == '9' {
|
||||
num[start] = '0'
|
||||
copy(num[start+1:], num[start:end])
|
||||
end++
|
||||
if dot == start && end == start+1 {
|
||||
num[start] = '1'
|
||||
} else if num[start] == '9' {
|
||||
num[start] = '1'
|
||||
num[start+1] = '0'
|
||||
end++
|
||||
} else {
|
||||
num[start]++
|
||||
}
|
||||
|
@ -187,13 +189,17 @@ func Decimal(num []byte, prec int) []byte {
|
|||
|
||||
// Number minifies a given byte slice containing a number (see parse.Number) and removes superfluous characters.
|
||||
func Number(num []byte, prec int) []byte {
|
||||
if len(num) <= 1 {
|
||||
return num
|
||||
}
|
||||
|
||||
// omit first + and register mantissa start and end, whether it's negative and the exponent
|
||||
neg := false
|
||||
start := 0
|
||||
dot := -1
|
||||
end := len(num)
|
||||
origExp := 0
|
||||
if 0 < end && (num[0] == '+' || num[0] == '-') {
|
||||
if num[0] == '+' || num[0] == '-' {
|
||||
if num[0] == '-' {
|
||||
neg = true
|
||||
}
|
||||
|
@ -208,7 +214,7 @@ func Number(num []byte, prec int) []byte {
|
|||
if i < len(num) && num[i] == '+' {
|
||||
i++
|
||||
}
|
||||
if tmpOrigExp, n := strconv.ParseInt(num[i:]); n > 0 && tmpOrigExp >= int64(MinInt) && tmpOrigExp <= int64(MaxInt) {
|
||||
if tmpOrigExp, n := strconv.ParseInt(num[i:]); 0 < n && int64(MinInt) <= tmpOrigExp && tmpOrigExp <= int64(MaxInt) {
|
||||
// range checks for when int is 32 bit
|
||||
origExp = int(tmpOrigExp)
|
||||
} else {
|
||||
|
@ -227,7 +233,7 @@ func Number(num []byte, prec int) []byte {
|
|||
}
|
||||
// trim trailing zeros
|
||||
i := end - 1
|
||||
for ; i > dot; i-- {
|
||||
for ; dot < i; i-- {
|
||||
if num[i] != '0' {
|
||||
end = i + 1
|
||||
break
|
||||
|
@ -243,6 +249,61 @@ func Number(num []byte, prec int) []byte {
|
|||
return num[start:end]
|
||||
}
|
||||
|
||||
// apply precision
|
||||
if 0 < prec { //&& (dot <= start+prec || start+prec+1 < dot || 0 < origExp) { // don't minify 9 to 10, but do 999 to 1e3 and 99e1 to 1e3
|
||||
precEnd := start + prec
|
||||
if dot == start { // for numbers like .012
|
||||
digit := start + 1
|
||||
for digit < end && num[digit] == '0' {
|
||||
digit++
|
||||
}
|
||||
precEnd = digit + prec
|
||||
} else if dot < precEnd { // for numbers where precision will include the dot
|
||||
precEnd++
|
||||
}
|
||||
if precEnd < end && (dot < end || 1 < dot-precEnd+origExp) { // do not minify 9=>10 or 99=>100 or 9e1=>1e2 (but 90), but 999=>1e3 and 99e1=>1e3
|
||||
end = precEnd
|
||||
inc := '5' <= num[end]
|
||||
if dot == end {
|
||||
inc = end+1 < len(num) && '5' <= num[end+1]
|
||||
}
|
||||
if precEnd < dot {
|
||||
origExp += dot - precEnd
|
||||
dot = precEnd
|
||||
}
|
||||
// process either an increase from a lesser significant decimal (>= 5)
|
||||
// and remove trailing zeros
|
||||
i := end - 1
|
||||
for ; start < i; i-- {
|
||||
if i == dot {
|
||||
// no-op
|
||||
} else if inc && num[i] != '9' {
|
||||
num[i]++
|
||||
inc = false
|
||||
break
|
||||
} else if !inc && num[i] != '0' {
|
||||
break
|
||||
}
|
||||
}
|
||||
end = i + 1
|
||||
if end < dot {
|
||||
origExp += dot - end
|
||||
dot = end
|
||||
}
|
||||
if inc { // single digit left
|
||||
if dot == start {
|
||||
num[start] = '1'
|
||||
dot = start + 1
|
||||
} else if num[start] == '9' {
|
||||
num[start] = '1'
|
||||
origExp++
|
||||
} else {
|
||||
num[start]++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// n is the number of significant digits
|
||||
// normExp would be the exponent if it were normalised (0.1 <= f < 1)
|
||||
n := 0
|
||||
|
@ -257,7 +318,7 @@ func Number(num []byte, prec int) []byte {
|
|||
}
|
||||
} else if dot == end {
|
||||
normExp = end - start
|
||||
for i = end - 1; i >= start; i-- {
|
||||
for i = end - 1; start <= i; i-- {
|
||||
if num[i] != '0' {
|
||||
n = i + 1 - start
|
||||
end = i + 1
|
||||
|
@ -269,68 +330,87 @@ func Number(num []byte, prec int) []byte {
|
|||
normExp = dot - start
|
||||
}
|
||||
|
||||
if origExp < 0 && (normExp < MinInt-origExp || normExp-n < MinInt-origExp) || origExp > 0 && (normExp > MaxInt-origExp || normExp-n > MaxInt-origExp) {
|
||||
return num
|
||||
if origExp < 0 && (normExp < MinInt-origExp || normExp-n < MinInt-origExp) || 0 < origExp && (MaxInt-origExp < normExp || MaxInt-origExp < normExp-n) {
|
||||
return num // exponent overflow
|
||||
}
|
||||
normExp += origExp
|
||||
|
||||
// intExp would be the exponent if it were an integer
|
||||
intExp := normExp - n
|
||||
lenIntExp := 1
|
||||
if intExp <= -10 || intExp >= 10 {
|
||||
lenIntExp = strconv.LenInt(int64(intExp))
|
||||
}
|
||||
lenIntExp := strconv.LenInt(int64(intExp))
|
||||
lenNormExp := strconv.LenInt(int64(normExp))
|
||||
|
||||
// there are three cases to consider when printing the number
|
||||
// case 1: without decimals and with an exponent (large numbers)
|
||||
// case 2: with decimals and without an exponent (around zero)
|
||||
// case 3: without decimals and with a negative exponent (small numbers)
|
||||
if normExp >= n {
|
||||
// case 1
|
||||
// case 1: without decimals and with a positive exponent (large numbers: 5e4)
|
||||
// case 2: with decimals and with a negative exponent (small numbers with many digits: .123456e-4)
|
||||
// case 3: with decimals and without an exponent (around zero: 5.6)
|
||||
// case 4: without decimals and with a negative exponent (small numbers: 123456e-9)
|
||||
if n <= normExp {
|
||||
// case 1: print number with positive exponent
|
||||
if dot < end {
|
||||
// remove dot, either from the front or copy the smallest part
|
||||
if dot == start {
|
||||
start = end - n
|
||||
} else if dot-start < end-dot-1 {
|
||||
copy(num[start+1:], num[start:dot])
|
||||
start++
|
||||
} else {
|
||||
// TODO: copy the other part if shorter?
|
||||
copy(num[dot:], num[dot+1:end])
|
||||
end--
|
||||
}
|
||||
}
|
||||
if normExp >= n+3 {
|
||||
if n+3 <= normExp {
|
||||
num[end] = 'e'
|
||||
end++
|
||||
for i := end + lenIntExp - 1; i >= end; i-- {
|
||||
for i := end + lenIntExp - 1; end <= i; i-- {
|
||||
num[i] = byte(intExp%10) + '0'
|
||||
intExp /= 10
|
||||
}
|
||||
end += lenIntExp
|
||||
} else if normExp == n+2 {
|
||||
} else if n+2 == normExp {
|
||||
num[end] = '0'
|
||||
num[end+1] = '0'
|
||||
end += 2
|
||||
} else if normExp == n+1 {
|
||||
} else if n+1 == normExp {
|
||||
num[end] = '0'
|
||||
end++
|
||||
}
|
||||
} else if normExp >= -lenIntExp-1 {
|
||||
// case 2
|
||||
} else if normExp < -3 && lenNormExp < lenIntExp {
|
||||
// case 2: print normalized number (0.1 <= f < 1)
|
||||
zeroes := -normExp + origExp
|
||||
if 0 < zeroes {
|
||||
copy(num[start+1:], num[start+1+zeroes:end])
|
||||
end -= zeroes
|
||||
} else if zeroes < 0 {
|
||||
copy(num[start+1:], num[start:dot])
|
||||
num[start] = '.'
|
||||
}
|
||||
num[end] = 'e'
|
||||
num[end+1] = '-'
|
||||
end += 2
|
||||
for i := end + lenNormExp - 1; end <= i; i-- {
|
||||
num[i] = -byte(normExp%10) + '0'
|
||||
normExp /= 10
|
||||
}
|
||||
end += lenNormExp
|
||||
} else if -lenIntExp-1 <= normExp {
|
||||
// case 3: print number without exponent
|
||||
zeroes := -normExp
|
||||
newDot := 0
|
||||
if zeroes > 0 {
|
||||
// dot placed at the front and add zeroes
|
||||
newDot = end - n - zeroes - 1
|
||||
if 0 < zeroes {
|
||||
// dot placed at the front and negative exponent, adding zeroes
|
||||
newDot := end - n - zeroes - 1
|
||||
if newDot != dot {
|
||||
d := start - newDot
|
||||
if d > 0 {
|
||||
if 0 < d {
|
||||
if dot < end {
|
||||
// copy original digits behind the dot backwards
|
||||
// copy original digits after the dot towards the end
|
||||
copy(num[dot+1+d:], num[dot+1:end])
|
||||
if dot > start {
|
||||
// copy original digits before the dot backwards
|
||||
if start < dot {
|
||||
// copy original digits before the dot towards the end
|
||||
copy(num[start+d+1:], num[start:dot])
|
||||
}
|
||||
} else if dot > start {
|
||||
// copy original digits before the dot backwards
|
||||
} else if start < dot {
|
||||
// copy original digits before the dot towards the end
|
||||
copy(num[start+d:], num[start:dot])
|
||||
}
|
||||
newDot = start
|
||||
|
@ -344,83 +424,27 @@ func Number(num []byte, prec int) []byte {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// placed in the middle
|
||||
// dot placed in the middle of the number
|
||||
if dot == start {
|
||||
// TODO: try if placing at the end reduces copying
|
||||
// when there are zeroes after the dot
|
||||
dot = end - n - 1
|
||||
start = dot
|
||||
} else if dot >= end {
|
||||
// TODO: try if placing at the start reduces copying
|
||||
} else if end <= dot {
|
||||
// when input has no dot in it
|
||||
dot = end
|
||||
end++
|
||||
}
|
||||
newDot = start + normExp
|
||||
if newDot > dot {
|
||||
// copy digits forwards
|
||||
newDot := start + normExp
|
||||
// move digits between dot and newDot towards the end
|
||||
if dot < newDot {
|
||||
copy(num[dot:], num[dot+1:newDot+1])
|
||||
} else if newDot < dot {
|
||||
// copy digits backwards
|
||||
copy(num[newDot+1:], num[newDot:dot])
|
||||
}
|
||||
num[newDot] = '.'
|
||||
}
|
||||
|
||||
// apply precision
|
||||
dot = newDot
|
||||
if prec > -1 && dot+1+prec < end {
|
||||
end = dot + 1 + prec
|
||||
inc := num[end] >= '5'
|
||||
if inc || num[end-1] == '0' {
|
||||
for i := end - 1; i > start; i-- {
|
||||
if i == dot {
|
||||
end--
|
||||
} else if inc {
|
||||
if num[i] == '9' {
|
||||
if i > dot {
|
||||
end--
|
||||
} else {
|
||||
num[i] = '0'
|
||||
break
|
||||
}
|
||||
} else {
|
||||
num[i]++
|
||||
inc = false
|
||||
break
|
||||
}
|
||||
} else if i > dot && num[i] == '0' {
|
||||
end--
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if dot == start && end == start+1 {
|
||||
if inc {
|
||||
num[start] = '1'
|
||||
} else {
|
||||
num[start] = '0'
|
||||
}
|
||||
} else {
|
||||
if dot+1 == end {
|
||||
end--
|
||||
}
|
||||
if inc {
|
||||
if num[start] == '9' {
|
||||
num[start] = '0'
|
||||
copy(num[start+1:], num[start:end])
|
||||
end++
|
||||
num[start] = '1'
|
||||
} else {
|
||||
num[start]++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// case 3
|
||||
|
||||
// case 4: print number with negative exponent
|
||||
// find new end, considering moving numbers to the front, removing the dot and increasing the length of the exponent
|
||||
newEnd := end
|
||||
if dot == start {
|
||||
|
@ -447,16 +471,15 @@ func Number(num []byte, prec int) []byte {
|
|||
// it does not save space and will panic, so we revert to the original representation
|
||||
exp = origExp
|
||||
lenExp = 1
|
||||
if origExp <= -10 || origExp >= 10 {
|
||||
if origExp <= -10 || 10 <= origExp {
|
||||
lenExp = strconv.LenInt(int64(origExp))
|
||||
}
|
||||
}
|
||||
num[end] = 'e'
|
||||
num[end+1] = '-'
|
||||
end += 2
|
||||
exp = -exp
|
||||
for i := end + lenExp - 1; i >= end; i-- {
|
||||
num[i] = byte(exp%10) + '0'
|
||||
for i := end + lenExp - 1; end <= i; i-- {
|
||||
num[i] = -byte(exp%10) + '0'
|
||||
exp /= 10
|
||||
}
|
||||
end += lenExp
|
||||
|
|
6
vendor/github.com/tdewolff/minify/v2/go.mod
generated
vendored
6
vendor/github.com/tdewolff/minify/v2/go.mod
generated
vendored
|
@ -1,6 +1,6 @@
|
|||
module github.com/tdewolff/minify/v2
|
||||
|
||||
//replace github.com/tdewolff/parse/v2 => ../parse
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect
|
||||
|
@ -8,7 +8,7 @@ require (
|
|||
github.com/fsnotify/fsnotify v1.4.7
|
||||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2
|
||||
github.com/spf13/pflag v1.0.3
|
||||
github.com/tdewolff/parse/v2 v2.3.7
|
||||
github.com/tdewolff/test v1.0.0
|
||||
github.com/tdewolff/parse/v2 v2.4.2
|
||||
github.com/tdewolff/test v1.0.6
|
||||
golang.org/x/sys v0.0.0-20181031143558-9b800f95dbbc // indirect
|
||||
)
|
||||
|
|
10
vendor/github.com/tdewolff/minify/v2/go.sum
generated
vendored
10
vendor/github.com/tdewolff/minify/v2/go.sum
generated
vendored
|
@ -8,9 +8,11 @@ github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2 h1:JAEbJn3j/FrhdWA9jW8
|
|||
github.com/matryer/try v0.0.0-20161228173917-9ac251b645a2/go.mod h1:0KeJpeMD6o+O4hW7qJOT7vyQPKrWmj26uf5wMc/IiIs=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/tdewolff/parse/v2 v2.3.7 h1:DXoTUgrUE2Eap0m7zg1ljCO5C78vhEi7HTc4YnJWrRk=
|
||||
github.com/tdewolff/parse/v2 v2.3.7/go.mod h1:HansaqmN4I/U7L6/tUp0NcwT2tFO0F4EAWYGSDzkYNk=
|
||||
github.com/tdewolff/test v1.0.0 h1:jOwzqCXr5ePXEPGJaq2ivoR6HOCi+D5TPfpoyg8yvmU=
|
||||
github.com/tdewolff/test v1.0.0/go.mod h1:DiQUlutnqlEvdvhSn2LPGy4TFwRauAaYDsL+683RNX4=
|
||||
github.com/tdewolff/parse/v2 v2.4.2-0.20191217133525-7b246f800500 h1:FlcpXrF3rpbZ8lxK0BcPnl3NEDuebxk+A9Wwm/tjDH4=
|
||||
github.com/tdewolff/parse/v2 v2.4.2-0.20191217133525-7b246f800500/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
|
||||
github.com/tdewolff/parse/v2 v2.4.2 h1:Bu2Qv6wepkc+Ou7iB/qHjAhEImlAP5vedzlQRUdj3BI=
|
||||
github.com/tdewolff/parse/v2 v2.4.2/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
|
||||
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
|
||||
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||
golang.org/x/sys v0.0.0-20181031143558-9b800f95dbbc h1:SdCq5U4J+PpbSDIl9bM0V1e1Ug1jsnBkAFvTs1htn7U=
|
||||
golang.org/x/sys v0.0.0-20181031143558-9b800f95dbbc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
|
12
vendor/github.com/tdewolff/minify/v2/html/buffer.go
generated
vendored
12
vendor/github.com/tdewolff/minify/v2/html/buffer.go
generated
vendored
|
@ -1,4 +1,4 @@
|
|||
package html // import "github.com/tdewolff/minify/html"
|
||||
package html
|
||||
|
||||
import (
|
||||
"github.com/tdewolff/parse/v2"
|
||||
|
@ -8,7 +8,7 @@ import (
|
|||
// Token is a single token unit with an attribute value (if given) and hash of the data.
|
||||
type Token struct {
|
||||
html.TokenType
|
||||
Hash html.Hash
|
||||
Hash Hash
|
||||
Data []byte
|
||||
Text []byte
|
||||
AttrVal []byte
|
||||
|
@ -41,12 +41,12 @@ func (z *TokenBuffer) read(t *Token) {
|
|||
if len(t.AttrVal) > 1 && (t.AttrVal[0] == '"' || t.AttrVal[0] == '\'') {
|
||||
t.AttrVal = parse.TrimWhitespace(t.AttrVal[1 : len(t.AttrVal)-1]) // quotes will be readded in attribute loop if necessary
|
||||
}
|
||||
t.Hash = html.ToHash(t.Text)
|
||||
t.Hash = ToHash(t.Text)
|
||||
t.Traits = attrMap[t.Hash]
|
||||
} else if t.TokenType == html.StartTagToken || t.TokenType == html.EndTagToken {
|
||||
t.AttrVal = nil
|
||||
t.Hash = html.ToHash(t.Text)
|
||||
t.Traits = tagMap[t.Hash]
|
||||
t.Hash = ToHash(t.Text)
|
||||
t.Traits = tagMap[t.Hash] // zero if not exist
|
||||
} else {
|
||||
t.AttrVal = nil
|
||||
t.Hash = 0
|
||||
|
@ -103,7 +103,7 @@ func (z *TokenBuffer) Shift() *Token {
|
|||
|
||||
// Attributes extracts the gives attribute hashes from a tag.
|
||||
// It returns in the same order pointers to the requested token data or nil.
|
||||
func (z *TokenBuffer) Attributes(hashes ...html.Hash) []*Token {
|
||||
func (z *TokenBuffer) Attributes(hashes ...Hash) []*Token {
|
||||
n := 0
|
||||
for {
|
||||
if t := z.Peek(n); t.TokenType != html.AttributeToken {
|
||||
|
|
543
vendor/github.com/tdewolff/minify/v2/html/hash.go
generated
vendored
Normal file
543
vendor/github.com/tdewolff/minify/v2/html/hash.go
generated
vendored
Normal file
|
@ -0,0 +1,543 @@
|
|||
package html
|
||||
|
||||
// generated by hasher -type=Hash -file=hash.go; DO NOT EDIT, except for adding more constants to the list and rerun go generate
|
||||
|
||||
// uses github.com/tdewolff/hasher
|
||||
//go:generate hasher -type=Hash -file=hash.go
|
||||
|
||||
// Hash defines perfect hashes for a predefined list of strings
|
||||
type Hash uint32
|
||||
|
||||
// Unique hash definitions to be used instead of strings
|
||||
const (
|
||||
A Hash = 0x1 // a
|
||||
Abbr Hash = 0x37a04 // abbr
|
||||
About Hash = 0x5 // about
|
||||
Accept Hash = 0x1106 // accept
|
||||
Accept_Charset Hash = 0x110e // accept-charset
|
||||
Action Hash = 0x23f06 // action
|
||||
Address Hash = 0x5a07 // address
|
||||
Align Hash = 0x32705 // align
|
||||
Alink Hash = 0x7005 // alink
|
||||
Allowfullscreen Hash = 0x2ad0f // allowfullscreen
|
||||
Amp_Boilerplate Hash = 0x610f // amp-boilerplate
|
||||
Area Hash = 0x1e304 // area
|
||||
Article Hash = 0x2707 // article
|
||||
Aside Hash = 0xb405 // aside
|
||||
Async Hash = 0xac05 // async
|
||||
Audio Hash = 0xd105 // audio
|
||||
Autofocus Hash = 0xe409 // autofocus
|
||||
Autoplay Hash = 0x10808 // autoplay
|
||||
Axis Hash = 0x11004 // axis
|
||||
B Hash = 0x101 // b
|
||||
Background Hash = 0x300a // background
|
||||
Base Hash = 0x19604 // base
|
||||
Bb Hash = 0x37b02 // bb
|
||||
Bdi Hash = 0x7503 // bdi
|
||||
Bdo Hash = 0x31f03 // bdo
|
||||
Bgcolor Hash = 0x12607 // bgcolor
|
||||
Blockquote Hash = 0x13e0a // blockquote
|
||||
Body Hash = 0xd04 // body
|
||||
Br Hash = 0x37c02 // br
|
||||
Button Hash = 0x14806 // button
|
||||
Canvas Hash = 0xb006 // canvas
|
||||
Caption Hash = 0x21f07 // caption
|
||||
Charset Hash = 0x1807 // charset
|
||||
Checked Hash = 0x1b307 // checked
|
||||
Cite Hash = 0xfb04 // cite
|
||||
Class Hash = 0x15905 // class
|
||||
Classid Hash = 0x15907 // classid
|
||||
Clear Hash = 0x2b05 // clear
|
||||
Code Hash = 0x19204 // code
|
||||
Codebase Hash = 0x19208 // codebase
|
||||
Codetype Hash = 0x1a408 // codetype
|
||||
Col Hash = 0x12803 // col
|
||||
Colgroup Hash = 0x1bb08 // colgroup
|
||||
Color Hash = 0x12805 // color
|
||||
Cols Hash = 0x1cf04 // cols
|
||||
Colspan Hash = 0x1cf07 // colspan
|
||||
Compact Hash = 0x1ec07 // compact
|
||||
Content Hash = 0x28407 // content
|
||||
Controls Hash = 0x20108 // controls
|
||||
Data Hash = 0x1f04 // data
|
||||
Datalist Hash = 0x1f08 // datalist
|
||||
Datatype Hash = 0x4d08 // datatype
|
||||
Dd Hash = 0x5b02 // dd
|
||||
Declare Hash = 0xb707 // declare
|
||||
Default Hash = 0x7f07 // default
|
||||
DefaultChecked Hash = 0x1730e // defaultChecked
|
||||
DefaultMuted Hash = 0x7f0c // defaultMuted
|
||||
DefaultSelected Hash = 0x8a0f // defaultSelected
|
||||
Defer Hash = 0x9805 // defer
|
||||
Del Hash = 0x10503 // del
|
||||
Details Hash = 0x15f07 // details
|
||||
Dfn Hash = 0x16c03 // dfn
|
||||
Dialog Hash = 0xa606 // dialog
|
||||
Dir Hash = 0x7603 // dir
|
||||
Disabled Hash = 0x18008 // disabled
|
||||
Div Hash = 0x18703 // div
|
||||
Dl Hash = 0x1b902 // dl
|
||||
Dt Hash = 0x23102 // dt
|
||||
Em Hash = 0x4302 // em
|
||||
Embed Hash = 0x4905 // embed
|
||||
Enabled Hash = 0x26c07 // enabled
|
||||
Enctype Hash = 0x1fa07 // enctype
|
||||
Face Hash = 0x5604 // face
|
||||
Fieldset Hash = 0x21408 // fieldset
|
||||
Figcaption Hash = 0x21c0a // figcaption
|
||||
Figure Hash = 0x22606 // figure
|
||||
Footer Hash = 0xdb06 // footer
|
||||
For Hash = 0x23b03 // for
|
||||
Form Hash = 0x23b04 // form
|
||||
Formaction Hash = 0x23b0a // formaction
|
||||
Formnovalidate Hash = 0x2450e // formnovalidate
|
||||
Frame Hash = 0x28c05 // frame
|
||||
Frameborder Hash = 0x28c0b // frameborder
|
||||
H1 Hash = 0x2e002 // h1
|
||||
H2 Hash = 0x25302 // h2
|
||||
H3 Hash = 0x25502 // h3
|
||||
H4 Hash = 0x25702 // h4
|
||||
H5 Hash = 0x25902 // h5
|
||||
H6 Hash = 0x25b02 // h6
|
||||
Head Hash = 0x2d204 // head
|
||||
Header Hash = 0x2d206 // header
|
||||
Hgroup Hash = 0x25d06 // hgroup
|
||||
Hidden Hash = 0x26806 // hidden
|
||||
Hr Hash = 0x32d02 // hr
|
||||
Href Hash = 0x32d04 // href
|
||||
Hreflang Hash = 0x32d08 // hreflang
|
||||
Html Hash = 0x27304 // html
|
||||
Http_Equiv Hash = 0x2770a // http-equiv
|
||||
I Hash = 0x2401 // i
|
||||
Icon Hash = 0x28304 // icon
|
||||
Id Hash = 0xb602 // id
|
||||
Iframe Hash = 0x28b06 // iframe
|
||||
Img Hash = 0x29703 // img
|
||||
Inert Hash = 0xf605 // inert
|
||||
Inlist Hash = 0x29a06 // inlist
|
||||
Input Hash = 0x2a405 // input
|
||||
Ins Hash = 0x2a903 // ins
|
||||
Ismap Hash = 0x11205 // ismap
|
||||
Itemscope Hash = 0xfc09 // itemscope
|
||||
Kbd Hash = 0x7403 // kbd
|
||||
Keygen Hash = 0x1f606 // keygen
|
||||
Label Hash = 0xbe05 // label
|
||||
Lang Hash = 0x33104 // lang
|
||||
Language Hash = 0x33108 // language
|
||||
Legend Hash = 0x2c506 // legend
|
||||
Li Hash = 0x2302 // li
|
||||
Link Hash = 0x7104 // link
|
||||
Longdesc Hash = 0xc208 // longdesc
|
||||
Main Hash = 0xf404 // main
|
||||
Manifest Hash = 0x2bc08 // manifest
|
||||
Map Hash = 0xee03 // map
|
||||
Mark Hash = 0x2cb04 // mark
|
||||
Math Hash = 0x2cf04 // math
|
||||
Max Hash = 0x2d803 // max
|
||||
Maxlength Hash = 0x2d809 // maxlength
|
||||
Media Hash = 0xa405 // media
|
||||
Menu Hash = 0x12204 // menu
|
||||
Meta Hash = 0x2e204 // meta
|
||||
Meter Hash = 0x2f705 // meter
|
||||
Method Hash = 0x2fc06 // method
|
||||
Multiple Hash = 0x30208 // multiple
|
||||
Muted Hash = 0x30a05 // muted
|
||||
Name Hash = 0xa204 // name
|
||||
Nav Hash = 0x32403 // nav
|
||||
Nohref Hash = 0x32b06 // nohref
|
||||
Noresize Hash = 0x13608 // noresize
|
||||
Noscript Hash = 0x14d08 // noscript
|
||||
Noshade Hash = 0x16e07 // noshade
|
||||
Novalidate Hash = 0x2490a // novalidate
|
||||
Nowrap Hash = 0x1d506 // nowrap
|
||||
Object Hash = 0xd506 // object
|
||||
Ol Hash = 0xcb02 // ol
|
||||
Open Hash = 0x32104 // open
|
||||
Optgroup Hash = 0x35608 // optgroup
|
||||
Option Hash = 0x30f06 // option
|
||||
Output Hash = 0x206 // output
|
||||
P Hash = 0x501 // p
|
||||
Param Hash = 0xf005 // param
|
||||
Pauseonexit Hash = 0x1160b // pauseonexit
|
||||
Picture Hash = 0x1c207 // picture
|
||||
Plaintext Hash = 0x1da09 // plaintext
|
||||
Poster Hash = 0x26206 // poster
|
||||
Pre Hash = 0x35d03 // pre
|
||||
Prefix Hash = 0x35d06 // prefix
|
||||
Profile Hash = 0x36407 // profile
|
||||
Progress Hash = 0x34208 // progress
|
||||
Property Hash = 0x31508 // property
|
||||
Q Hash = 0x14301 // q
|
||||
Rb Hash = 0x2f02 // rb
|
||||
Readonly Hash = 0x1e408 // readonly
|
||||
Rel Hash = 0xbc03 // rel
|
||||
Required Hash = 0x22a08 // required
|
||||
Resource Hash = 0x1c708 // resource
|
||||
Rev Hash = 0x7803 // rev
|
||||
Reversed Hash = 0x7808 // reversed
|
||||
Rows Hash = 0x9c04 // rows
|
||||
Rowspan Hash = 0x9c07 // rowspan
|
||||
Rp Hash = 0x6a02 // rp
|
||||
Rt Hash = 0x2802 // rt
|
||||
Rtc Hash = 0xf903 // rtc
|
||||
Ruby Hash = 0xe004 // ruby
|
||||
Rules Hash = 0x12c05 // rules
|
||||
S Hash = 0x1c01 // s
|
||||
Samp Hash = 0x6004 // samp
|
||||
Scope Hash = 0x10005 // scope
|
||||
Scoped Hash = 0x10006 // scoped
|
||||
Script Hash = 0x14f06 // script
|
||||
Scrolling Hash = 0xc809 // scrolling
|
||||
Seamless Hash = 0x19808 // seamless
|
||||
Section Hash = 0x13007 // section
|
||||
Select Hash = 0x16506 // select
|
||||
Selected Hash = 0x16508 // selected
|
||||
Shape Hash = 0x19f05 // shape
|
||||
Size Hash = 0x13a04 // size
|
||||
Slot Hash = 0x20804 // slot
|
||||
Small Hash = 0x2ab05 // small
|
||||
Sortable Hash = 0x2ef08 // sortable
|
||||
Source Hash = 0x1c906 // source
|
||||
Span Hash = 0x9f04 // span
|
||||
Src Hash = 0x34903 // src
|
||||
Srcset Hash = 0x34906 // srcset
|
||||
Start Hash = 0x2505 // start
|
||||
Strong Hash = 0x29e06 // strong
|
||||
Style Hash = 0x2c205 // style
|
||||
Sub Hash = 0x31d03 // sub
|
||||
Summary Hash = 0x33907 // summary
|
||||
Sup Hash = 0x34003 // sup
|
||||
Svg Hash = 0x34f03 // svg
|
||||
Tabindex Hash = 0x2e408 // tabindex
|
||||
Table Hash = 0x2f205 // table
|
||||
Target Hash = 0x706 // target
|
||||
Tbody Hash = 0xc05 // tbody
|
||||
Td Hash = 0x1e02 // td
|
||||
Template Hash = 0x4208 // template
|
||||
Text Hash = 0x1df04 // text
|
||||
Textarea Hash = 0x1df08 // textarea
|
||||
Tfoot Hash = 0xda05 // tfoot
|
||||
Th Hash = 0x2d102 // th
|
||||
Thead Hash = 0x2d105 // thead
|
||||
Time Hash = 0x12004 // time
|
||||
Title Hash = 0x15405 // title
|
||||
Tr Hash = 0x1f202 // tr
|
||||
Track Hash = 0x1f205 // track
|
||||
Translate Hash = 0x20b09 // translate
|
||||
Truespeed Hash = 0x23209 // truespeed
|
||||
Type Hash = 0x5104 // type
|
||||
Typemustmatch Hash = 0x1a80d // typemustmatch
|
||||
Typeof Hash = 0x5106 // typeof
|
||||
U Hash = 0x301 // u
|
||||
Ul Hash = 0x8302 // ul
|
||||
Undeterminate Hash = 0x370d // undeterminate
|
||||
Usemap Hash = 0xeb06 // usemap
|
||||
Valign Hash = 0x32606 // valign
|
||||
Value Hash = 0x18905 // value
|
||||
Valuetype Hash = 0x18909 // valuetype
|
||||
Var Hash = 0x28003 // var
|
||||
Video Hash = 0x35205 // video
|
||||
Visible Hash = 0x36b07 // visible
|
||||
Vlink Hash = 0x37205 // vlink
|
||||
Vocab Hash = 0x37705 // vocab
|
||||
Wbr Hash = 0x37e03 // wbr
|
||||
Xmlns Hash = 0x2eb05 // xmlns
|
||||
Xmp Hash = 0x36203 // xmp
|
||||
)
|
||||
|
||||
// String returns the hash' name.
|
||||
func (i Hash) String() string {
|
||||
start := uint32(i >> 8)
|
||||
n := uint32(i & 0xff)
|
||||
if start+n > uint32(len(_Hash_text)) {
|
||||
return ""
|
||||
}
|
||||
return _Hash_text[start : start+n]
|
||||
}
|
||||
|
||||
// ToHash returns the hash whose name is s. It returns zero if there is no
|
||||
// such hash. It is case sensitive.
|
||||
func ToHash(s []byte) Hash {
|
||||
if len(s) == 0 || len(s) > _Hash_maxLen {
|
||||
return 0
|
||||
}
|
||||
h := uint32(_Hash_hash0)
|
||||
for i := 0; i < len(s); i++ {
|
||||
h ^= uint32(s[i])
|
||||
h *= 16777619
|
||||
}
|
||||
if i := _Hash_table[h&uint32(len(_Hash_table)-1)]; int(i&0xff) == len(s) {
|
||||
t := _Hash_text[i>>8 : i>>8+i&0xff]
|
||||
for i := 0; i < len(s); i++ {
|
||||
if t[i] != s[i] {
|
||||
goto NEXT
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
NEXT:
|
||||
if i := _Hash_table[(h>>16)&uint32(len(_Hash_table)-1)]; int(i&0xff) == len(s) {
|
||||
t := _Hash_text[i>>8 : i>>8+i&0xff]
|
||||
for i := 0; i < len(s); i++ {
|
||||
if t[i] != s[i] {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
const _Hash_hash0 = 0x9acb0442
|
||||
const _Hash_maxLen = 15
|
||||
const _Hash_text = "aboutputargetbodyaccept-charsetdatalistarticlearbackgroundet" +
|
||||
"erminatemplatembedatatypeofaceaddressamp-boilerplatealinkbdi" +
|
||||
"reversedefaultMutedefaultSelectedeferowspanamedialogasyncanv" +
|
||||
"asideclarelabelongdescrollingaudiobjectfooterubyautofocusema" +
|
||||
"paramainertcitemscopedelautoplayaxismapauseonexitimenubgcolo" +
|
||||
"rulesectionoresizeblockquotebuttonoscriptitleclassidetailsel" +
|
||||
"ectedfnoshadefaultCheckedisabledivaluetypecodebaseamlesshape" +
|
||||
"codetypemustmatcheckedlcolgroupicturesourcecolspanowraplaint" +
|
||||
"extareadonlycompactrackeygenctypecontrolslotranslatefieldset" +
|
||||
"figcaptionfigurequiredtruespeedformactionformnovalidateh2h3h" +
|
||||
"4h5h6hgrouposterhiddenabledhtmlhttp-equivaricontentiframebor" +
|
||||
"derimginlistronginputinsmallowfullscreenmanifestylegendmarkm" +
|
||||
"atheadermaxlength1metabindexmlnsortablemetermethodmultiplemu" +
|
||||
"tedoptionpropertysubdopenavalignohreflanguagesummarysuprogre" +
|
||||
"ssrcsetsvgvideoptgrouprefixmprofilevisiblevlinkvocabbrwbr"
|
||||
|
||||
var _Hash_table = [1 << 9]Hash{
|
||||
0x0: 0x1df08, // textarea
|
||||
0x4: 0x32d02, // hr
|
||||
0x8: 0x1c207, // picture
|
||||
0xb: 0x18905, // value
|
||||
0xf: 0x2e408, // tabindex
|
||||
0x12: 0x15905, // class
|
||||
0x15: 0x37e03, // wbr
|
||||
0x18: 0x1a80d, // typemustmatch
|
||||
0x1a: 0x1b902, // dl
|
||||
0x1d: 0xf903, // rtc
|
||||
0x1e: 0x25702, // h4
|
||||
0x22: 0x2ef08, // sortable
|
||||
0x24: 0x4208, // template
|
||||
0x25: 0x28c0b, // frameborder
|
||||
0x28: 0x37a04, // abbr
|
||||
0x29: 0x28b06, // iframe
|
||||
0x2a: 0x610f, // amp-boilerplate
|
||||
0x2c: 0x1e408, // readonly
|
||||
0x30: 0x23f06, // action
|
||||
0x33: 0x28c05, // frame
|
||||
0x35: 0x12c05, // rules
|
||||
0x36: 0x30208, // multiple
|
||||
0x38: 0x31f03, // bdo
|
||||
0x39: 0x1d506, // nowrap
|
||||
0x3e: 0x21408, // fieldset
|
||||
0x3f: 0x7503, // bdi
|
||||
0x46: 0x7f0c, // defaultMuted
|
||||
0x49: 0x35205, // video
|
||||
0x4c: 0x19808, // seamless
|
||||
0x4d: 0x13608, // noresize
|
||||
0x4f: 0xb602, // id
|
||||
0x51: 0x25d06, // hgroup
|
||||
0x52: 0x23102, // dt
|
||||
0x55: 0x12805, // color
|
||||
0x56: 0x34003, // sup
|
||||
0x59: 0x370d, // undeterminate
|
||||
0x5a: 0x35608, // optgroup
|
||||
0x5b: 0x2d206, // header
|
||||
0x5c: 0xb405, // aside
|
||||
0x5f: 0x10005, // scope
|
||||
0x60: 0x101, // b
|
||||
0x61: 0xcb02, // ol
|
||||
0x64: 0x32b06, // nohref
|
||||
0x65: 0x1da09, // plaintext
|
||||
0x66: 0x20804, // slot
|
||||
0x67: 0x11004, // axis
|
||||
0x68: 0x12803, // col
|
||||
0x69: 0x32606, // valign
|
||||
0x6c: 0x2d105, // thead
|
||||
0x70: 0x34906, // srcset
|
||||
0x71: 0x26806, // hidden
|
||||
0x76: 0x1bb08, // colgroup
|
||||
0x78: 0x34f03, // svg
|
||||
0x7b: 0x2cb04, // mark
|
||||
0x7e: 0x33104, // lang
|
||||
0x81: 0x1cf04, // cols
|
||||
0x86: 0x5a07, // address
|
||||
0x8b: 0xf404, // main
|
||||
0x8c: 0x4302, // em
|
||||
0x8f: 0x32d08, // hreflang
|
||||
0x93: 0x1b307, // checked
|
||||
0x94: 0x25902, // h5
|
||||
0x95: 0x301, // u
|
||||
0x96: 0x32705, // align
|
||||
0x97: 0x14301, // q
|
||||
0x99: 0xd506, // object
|
||||
0x9b: 0x28407, // content
|
||||
0x9d: 0xc809, // scrolling
|
||||
0x9f: 0x36407, // profile
|
||||
0xa0: 0x34903, // src
|
||||
0xa1: 0xda05, // tfoot
|
||||
0xa3: 0x2f705, // meter
|
||||
0xa4: 0x37705, // vocab
|
||||
0xa6: 0xd04, // body
|
||||
0xa8: 0x19204, // code
|
||||
0xac: 0x20108, // controls
|
||||
0xb0: 0x2ab05, // small
|
||||
0xb1: 0x18008, // disabled
|
||||
0xb5: 0x5604, // face
|
||||
0xb6: 0x501, // p
|
||||
0xb9: 0x2302, // li
|
||||
0xbb: 0xe409, // autofocus
|
||||
0xbf: 0x27304, // html
|
||||
0xc2: 0x4d08, // datatype
|
||||
0xc6: 0x35d06, // prefix
|
||||
0xcb: 0x35d03, // pre
|
||||
0xcc: 0x1106, // accept
|
||||
0xd1: 0x23b03, // for
|
||||
0xd5: 0x29e06, // strong
|
||||
0xd6: 0x9c07, // rowspan
|
||||
0xd7: 0x25502, // h3
|
||||
0xd8: 0x2cf04, // math
|
||||
0xde: 0x16e07, // noshade
|
||||
0xdf: 0x19f05, // shape
|
||||
0xe1: 0x10006, // scoped
|
||||
0xe3: 0x706, // target
|
||||
0xe6: 0x21c0a, // figcaption
|
||||
0xe9: 0x1df04, // text
|
||||
0xea: 0x1c708, // resource
|
||||
0xec: 0xee03, // map
|
||||
0xf0: 0x29a06, // inlist
|
||||
0xf1: 0x16506, // select
|
||||
0xf2: 0x1f606, // keygen
|
||||
0xf3: 0x5106, // typeof
|
||||
0xf6: 0xb006, // canvas
|
||||
0xf7: 0x30f06, // option
|
||||
0xf8: 0xbe05, // label
|
||||
0xf9: 0xbc03, // rel
|
||||
0xfb: 0x1f04, // data
|
||||
0xfd: 0x6004, // samp
|
||||
0x100: 0x110e, // accept-charset
|
||||
0x101: 0xeb06, // usemap
|
||||
0x103: 0x2bc08, // manifest
|
||||
0x109: 0xa204, // name
|
||||
0x10a: 0x14806, // button
|
||||
0x10b: 0x2b05, // clear
|
||||
0x10e: 0x33907, // summary
|
||||
0x10f: 0x2e204, // meta
|
||||
0x110: 0x33108, // language
|
||||
0x112: 0x300a, // background
|
||||
0x113: 0x2707, // article
|
||||
0x116: 0x23b0a, // formaction
|
||||
0x119: 0x1, // a
|
||||
0x11b: 0x5, // about
|
||||
0x11c: 0xfc09, // itemscope
|
||||
0x11e: 0x14d08, // noscript
|
||||
0x11f: 0x15907, // classid
|
||||
0x120: 0x36203, // xmp
|
||||
0x121: 0x19604, // base
|
||||
0x123: 0x1c01, // s
|
||||
0x124: 0x36b07, // visible
|
||||
0x126: 0x37b02, // bb
|
||||
0x127: 0x9c04, // rows
|
||||
0x12d: 0x2450e, // formnovalidate
|
||||
0x131: 0x1f205, // track
|
||||
0x135: 0x18703, // div
|
||||
0x136: 0xac05, // async
|
||||
0x137: 0x31508, // property
|
||||
0x13a: 0x16c03, // dfn
|
||||
0x13e: 0xf605, // inert
|
||||
0x142: 0x10503, // del
|
||||
0x144: 0x25302, // h2
|
||||
0x147: 0x2c205, // style
|
||||
0x149: 0x29703, // img
|
||||
0x14a: 0xc05, // tbody
|
||||
0x14b: 0x7603, // dir
|
||||
0x14c: 0x2eb05, // xmlns
|
||||
0x14e: 0x1f08, // datalist
|
||||
0x14f: 0x32d04, // href
|
||||
0x150: 0x1f202, // tr
|
||||
0x151: 0x13e0a, // blockquote
|
||||
0x152: 0x18909, // valuetype
|
||||
0x155: 0xdb06, // footer
|
||||
0x157: 0x14f06, // script
|
||||
0x158: 0x1cf07, // colspan
|
||||
0x15d: 0x1730e, // defaultChecked
|
||||
0x15f: 0x2490a, // novalidate
|
||||
0x164: 0x1a408, // codetype
|
||||
0x165: 0x2c506, // legend
|
||||
0x16b: 0x1160b, // pauseonexit
|
||||
0x16c: 0x21f07, // caption
|
||||
0x16f: 0x26c07, // enabled
|
||||
0x173: 0x26206, // poster
|
||||
0x175: 0x30a05, // muted
|
||||
0x176: 0x11205, // ismap
|
||||
0x178: 0x2a903, // ins
|
||||
0x17a: 0xe004, // ruby
|
||||
0x17b: 0x37c02, // br
|
||||
0x17c: 0x8a0f, // defaultSelected
|
||||
0x17d: 0x7403, // kbd
|
||||
0x17f: 0x1c906, // source
|
||||
0x182: 0x9f04, // span
|
||||
0x184: 0x2d803, // max
|
||||
0x18a: 0x5b02, // dd
|
||||
0x18b: 0x13a04, // size
|
||||
0x18c: 0xa405, // media
|
||||
0x18d: 0x19208, // codebase
|
||||
0x18f: 0x4905, // embed
|
||||
0x192: 0x5104, // type
|
||||
0x193: 0xf005, // param
|
||||
0x194: 0x25b02, // h6
|
||||
0x197: 0x28304, // icon
|
||||
0x198: 0x12607, // bgcolor
|
||||
0x199: 0x2ad0f, // allowfullscreen
|
||||
0x19a: 0x12004, // time
|
||||
0x19b: 0x7803, // rev
|
||||
0x19d: 0x34208, // progress
|
||||
0x19e: 0x22606, // figure
|
||||
0x1a0: 0x6a02, // rp
|
||||
0x1a2: 0xa606, // dialog
|
||||
0x1a4: 0x2802, // rt
|
||||
0x1a7: 0x1e304, // area
|
||||
0x1a8: 0x7808, // reversed
|
||||
0x1aa: 0x32104, // open
|
||||
0x1ac: 0x2d204, // head
|
||||
0x1ad: 0x7005, // alink
|
||||
0x1af: 0x28003, // var
|
||||
0x1b0: 0x15f07, // details
|
||||
0x1b1: 0x2401, // i
|
||||
0x1b3: 0x1e02, // td
|
||||
0x1b4: 0xb707, // declare
|
||||
0x1b5: 0x8302, // ul
|
||||
0x1ba: 0x2fc06, // method
|
||||
0x1bd: 0x13007, // section
|
||||
0x1be: 0x22a08, // required
|
||||
0x1c2: 0x9805, // defer
|
||||
0x1c3: 0x37205, // vlink
|
||||
0x1c4: 0x15405, // title
|
||||
0x1c5: 0x2770a, // http-equiv
|
||||
0x1c6: 0x1fa07, // enctype
|
||||
0x1c7: 0x1ec07, // compact
|
||||
0x1c8: 0x2d809, // maxlength
|
||||
0x1c9: 0x16508, // selected
|
||||
0x1cc: 0xd105, // audio
|
||||
0x1cd: 0xc208, // longdesc
|
||||
0x1d1: 0xfb04, // cite
|
||||
0x1da: 0x2505, // start
|
||||
0x1de: 0x2d102, // th
|
||||
0x1df: 0x10808, // autoplay
|
||||
0x1e2: 0x7104, // link
|
||||
0x1e3: 0x206, // output
|
||||
0x1e5: 0x12204, // menu
|
||||
0x1e6: 0x2a405, // input
|
||||
0x1eb: 0x32403, // nav
|
||||
0x1ec: 0x31d03, // sub
|
||||
0x1ee: 0x1807, // charset
|
||||
0x1ef: 0x7f07, // default
|
||||
0x1f3: 0x2f205, // table
|
||||
0x1f4: 0x23b04, // form
|
||||
0x1f5: 0x23209, // truespeed
|
||||
0x1f6: 0x2f02, // rb
|
||||
0x1fb: 0x20b09, // translate
|
||||
0x1fd: 0x2e002, // h1
|
||||
}
|
234
vendor/github.com/tdewolff/minify/v2/html/html.go
generated
vendored
234
vendor/github.com/tdewolff/minify/v2/html/html.go
generated
vendored
|
@ -1,5 +1,5 @@
|
|||
// Package html minifies HTML5 following the specifications at http://www.w3.org/TR/html5/syntax.html.
|
||||
package html // import "github.com/tdewolff/minify/html"
|
||||
package html
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -38,6 +38,7 @@ type Minifier struct {
|
|||
KeepDefaultAttrVals bool
|
||||
KeepDocumentTags bool
|
||||
KeepEndTags bool
|
||||
KeepQuotes bool
|
||||
KeepWhitespace bool
|
||||
}
|
||||
|
||||
|
@ -48,7 +49,7 @@ func Minify(m *minify.M, w io.Writer, r io.Reader, params map[string]string) err
|
|||
|
||||
// Minify minifies HTML data, it reads from r and writes to w.
|
||||
func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
|
||||
var rawTagHash html.Hash
|
||||
var rawTagHash Hash
|
||||
var rawTagMediatype []byte
|
||||
|
||||
omitSpace := true // if true the next leading space is omitted
|
||||
|
@ -113,16 +114,16 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
case html.TextToken:
|
||||
// CSS and JS minifiers for inline code
|
||||
if rawTagHash != 0 {
|
||||
if rawTagHash == html.Style || rawTagHash == html.Script || rawTagHash == html.Iframe {
|
||||
if rawTagHash == Style || rawTagHash == Script || rawTagHash == Iframe {
|
||||
var mimetype []byte
|
||||
var params map[string]string
|
||||
if rawTagHash == html.Iframe {
|
||||
if rawTagHash == Iframe {
|
||||
mimetype = htmlMimeBytes
|
||||
} else if len(rawTagMediatype) > 0 {
|
||||
mimetype, params = parse.Mediatype(rawTagMediatype)
|
||||
} else if rawTagHash == html.Script {
|
||||
} else if rawTagHash == Script {
|
||||
mimetype = jsMimeBytes
|
||||
} else if rawTagHash == html.Style {
|
||||
} else if rawTagHash == Style {
|
||||
mimetype = cssMimeBytes
|
||||
}
|
||||
if err := m.MinifyMimetype(mimetype, w, buffer.NewReader(t.Data), params); err != nil {
|
||||
|
@ -140,10 +141,10 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
return err
|
||||
}
|
||||
} else {
|
||||
t.Data = parse.ReplaceMultipleWhitespace(t.Data)
|
||||
t.Data = parse.ReplaceMultipleWhitespaceAndEntities(t.Data, EntitiesMap, TextRevEntitiesMap)
|
||||
|
||||
// whitespace removal; trim left
|
||||
if omitSpace && (t.Data[0] == ' ' || t.Data[0] == '\n') {
|
||||
if omitSpace && parse.IsWhitespace(t.Data[0]) {
|
||||
t.Data = t.Data[1:]
|
||||
}
|
||||
|
||||
|
@ -151,7 +152,7 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
omitSpace = false
|
||||
if len(t.Data) == 0 {
|
||||
omitSpace = true
|
||||
} else if t.Data[len(t.Data)-1] == ' ' || t.Data[len(t.Data)-1] == '\n' {
|
||||
} else if parse.IsWhitespace(t.Data[len(t.Data)-1]) {
|
||||
omitSpace = true
|
||||
i := 0
|
||||
for {
|
||||
|
@ -199,7 +200,7 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
}
|
||||
if t.Traits&rawTag != 0 {
|
||||
// ignore empty script and style tags
|
||||
if !hasAttributes && (t.Hash == html.Script || t.Hash == html.Style) {
|
||||
if !hasAttributes && (t.Hash == Script || t.Hash == Style) {
|
||||
if next := tb.Peek(1); next.TokenType == html.EndTagToken {
|
||||
tb.Shift()
|
||||
tb.Shift()
|
||||
|
@ -208,25 +209,32 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
}
|
||||
rawTagHash = t.Hash
|
||||
rawTagMediatype = nil
|
||||
|
||||
// do not minify content of <style amp-boilerplate>
|
||||
if hasAttributes && t.Hash == Style {
|
||||
if attrs := tb.Attributes(Amp_Boilerplate); attrs[0] != nil {
|
||||
rawTagHash = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if t.Hash == html.Template {
|
||||
} else if t.Hash == Template {
|
||||
omitSpace = true // EndTagToken
|
||||
}
|
||||
|
||||
if t.Hash == html.Pre {
|
||||
if t.Hash == Pre {
|
||||
inPre = t.TokenType == html.StartTagToken
|
||||
}
|
||||
|
||||
// remove superfluous tags, except for html, head and body tags when KeepDocumentTags is set
|
||||
if !hasAttributes && (!o.KeepDocumentTags && (t.Hash == html.Html || t.Hash == html.Head || t.Hash == html.Body) || t.Hash == html.Colgroup) {
|
||||
if !hasAttributes && (!o.KeepDocumentTags && (t.Hash == Html || t.Hash == Head || t.Hash == Body) || t.Hash == Colgroup) {
|
||||
break
|
||||
} else if t.TokenType == html.EndTagToken {
|
||||
if !o.KeepEndTags {
|
||||
if t.Hash == html.Thead || t.Hash == html.Tbody || t.Hash == html.Tfoot || t.Hash == html.Tr || t.Hash == html.Th || t.Hash == html.Td ||
|
||||
t.Hash == html.Optgroup || t.Hash == html.Option || t.Hash == html.Dd || t.Hash == html.Dt ||
|
||||
t.Hash == html.Li || t.Hash == html.Rb || t.Hash == html.Rt || t.Hash == html.Rtc || t.Hash == html.Rp {
|
||||
if t.Hash == Thead || t.Hash == Tbody || t.Hash == Tfoot || t.Hash == Tr || t.Hash == Th || t.Hash == Td ||
|
||||
t.Hash == Optgroup || t.Hash == Option || t.Hash == Dd || t.Hash == Dt ||
|
||||
t.Hash == Li || t.Hash == Rb || t.Hash == Rt || t.Hash == Rtc || t.Hash == Rp {
|
||||
break
|
||||
} else if t.Hash == html.P {
|
||||
} else if t.Hash == P {
|
||||
i := 0
|
||||
for {
|
||||
next := tb.Peek(i)
|
||||
|
@ -270,8 +278,8 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
}
|
||||
|
||||
if hasAttributes {
|
||||
if t.Hash == html.Meta {
|
||||
attrs := tb.Attributes(html.Content, html.Http_Equiv, html.Charset, html.Name)
|
||||
if t.Hash == Meta {
|
||||
attrs := tb.Attributes(Content, Http_Equiv, Charset, Name)
|
||||
if content := attrs[0]; content != nil {
|
||||
if httpEquiv := attrs[1]; httpEquiv != nil {
|
||||
if charset := attrs[2]; charset == nil && parse.EqualFold(httpEquiv.AttrVal, []byte("content-type")) {
|
||||
|
@ -279,7 +287,7 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
if bytes.Equal(content.AttrVal, []byte("text/html;charset=utf-8")) {
|
||||
httpEquiv.Text = nil
|
||||
content.Text = []byte("charset")
|
||||
content.Hash = html.Charset
|
||||
content.Hash = Charset
|
||||
content.AttrVal = []byte("utf-8")
|
||||
}
|
||||
}
|
||||
|
@ -307,13 +315,13 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
}
|
||||
}
|
||||
}
|
||||
} else if t.Hash == html.Script {
|
||||
attrs := tb.Attributes(html.Src, html.Charset)
|
||||
} else if t.Hash == Script {
|
||||
attrs := tb.Attributes(Src, Charset)
|
||||
if attrs[0] != nil && attrs[1] != nil {
|
||||
attrs[1].Text = nil
|
||||
}
|
||||
} else if t.Hash == html.Input {
|
||||
attrs := tb.Attributes(html.Type, html.Value)
|
||||
} else if t.Hash == Input {
|
||||
attrs := tb.Attributes(Type, Value)
|
||||
if t, value := attrs[0], attrs[1]; t != nil && value != nil {
|
||||
isRadio := parse.EqualFold(t.AttrVal, []byte("radio"))
|
||||
if !isRadio && len(value.AttrVal) == 0 {
|
||||
|
@ -334,108 +342,112 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
continue // removed attribute
|
||||
}
|
||||
|
||||
if t.Hash == html.A && (attr.Hash == html.Id || attr.Hash == html.Name) {
|
||||
if attr.Hash == html.Id {
|
||||
if name := tb.Attributes(html.Name)[0]; name != nil && bytes.Equal(attr.AttrVal, name.AttrVal) {
|
||||
if t.Hash == A && (attr.Hash == Id || attr.Hash == Name) {
|
||||
if attr.Hash == Id {
|
||||
if name := tb.Attributes(Name)[0]; name != nil && bytes.Equal(attr.AttrVal, name.AttrVal) {
|
||||
htmlEqualIdName = true
|
||||
}
|
||||
} else if htmlEqualIdName {
|
||||
continue
|
||||
} else if id := tb.Attributes(html.Id)[0]; id != nil && bytes.Equal(id.AttrVal, attr.AttrVal) {
|
||||
} else if id := tb.Attributes(Id)[0]; id != nil && bytes.Equal(id.AttrVal, attr.AttrVal) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
val := attr.AttrVal
|
||||
if attr.Traits&trimAttr != 0 {
|
||||
val = parse.TrimWhitespace(val)
|
||||
val = parse.ReplaceMultipleWhitespace(val)
|
||||
val = parse.ReplaceMultipleWhitespaceAndEntities(val, EntitiesMap, nil)
|
||||
} else {
|
||||
val = parse.ReplaceEntities(val, EntitiesMap, nil)
|
||||
}
|
||||
if len(val) == 0 && (attr.Hash == html.Class ||
|
||||
attr.Hash == html.Dir ||
|
||||
attr.Hash == html.Id ||
|
||||
attr.Hash == html.Lang ||
|
||||
attr.Hash == html.Name ||
|
||||
attr.Hash == html.Title ||
|
||||
attr.Hash == html.Action && t.Hash == html.Form) {
|
||||
continue // omit empty attribute values
|
||||
}
|
||||
if attr.Traits&caselessAttr != 0 {
|
||||
val = parse.ToLower(val)
|
||||
if attr.Hash == html.Enctype || attr.Hash == html.Codetype || attr.Hash == html.Accept || attr.Hash == html.Type && (t.Hash == html.A || t.Hash == html.Link || t.Hash == html.Object || t.Hash == html.Param || t.Hash == html.Script || t.Hash == html.Style || t.Hash == html.Source) {
|
||||
val = minify.Mediatype(val)
|
||||
if t.Traits != 0 {
|
||||
if len(val) == 0 && (attr.Hash == Class ||
|
||||
attr.Hash == Dir ||
|
||||
attr.Hash == Id ||
|
||||
attr.Hash == Lang ||
|
||||
attr.Hash == Name ||
|
||||
attr.Hash == Title ||
|
||||
attr.Hash == Action && t.Hash == Form) {
|
||||
continue // omit empty attribute values
|
||||
}
|
||||
}
|
||||
if rawTagHash != 0 && attr.Hash == html.Type {
|
||||
rawTagMediatype = parse.Copy(val)
|
||||
}
|
||||
|
||||
// default attribute values can be omitted
|
||||
if !o.KeepDefaultAttrVals && (attr.Hash == html.Type && (t.Hash == html.Script && jsMimetypes[string(val)] ||
|
||||
t.Hash == html.Style && bytes.Equal(val, []byte("text/css")) ||
|
||||
t.Hash == html.Link && bytes.Equal(val, []byte("text/css")) ||
|
||||
t.Hash == html.Input && bytes.Equal(val, []byte("text")) ||
|
||||
t.Hash == html.Button && bytes.Equal(val, []byte("submit"))) ||
|
||||
attr.Hash == html.Language && t.Hash == html.Script ||
|
||||
attr.Hash == html.Method && bytes.Equal(val, []byte("get")) ||
|
||||
attr.Hash == html.Enctype && bytes.Equal(val, []byte("application/x-www-form-urlencoded")) ||
|
||||
attr.Hash == html.Colspan && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == html.Rowspan && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == html.Shape && bytes.Equal(val, []byte("rect")) ||
|
||||
attr.Hash == html.Span && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == html.Clear && bytes.Equal(val, []byte("none")) ||
|
||||
attr.Hash == html.Frameborder && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == html.Scrolling && bytes.Equal(val, []byte("auto")) ||
|
||||
attr.Hash == html.Valuetype && bytes.Equal(val, []byte("data")) ||
|
||||
attr.Hash == html.Media && t.Hash == html.Style && bytes.Equal(val, []byte("all"))) {
|
||||
continue
|
||||
}
|
||||
|
||||
// CSS and JS minifiers for attribute inline code
|
||||
if attr.Hash == html.Style {
|
||||
val = parse.TrimWhitespace(val)
|
||||
attrMinifyBuffer.Reset()
|
||||
if err := m.MinifyMimetype(cssMimeBytes, attrMinifyBuffer, buffer.NewReader(val), inlineParams); err == nil {
|
||||
val = attrMinifyBuffer.Bytes()
|
||||
} else if err != minify.ErrNotExist {
|
||||
return err
|
||||
if attr.Traits&caselessAttr != 0 {
|
||||
val = parse.ToLower(val)
|
||||
if attr.Hash == Enctype || attr.Hash == Codetype || attr.Hash == Accept || attr.Hash == Type && (t.Hash == A || t.Hash == Link || t.Hash == Embed || t.Hash == Object || t.Hash == Source || t.Hash == Script || t.Hash == Style) {
|
||||
val = minify.Mediatype(val)
|
||||
}
|
||||
}
|
||||
if len(val) == 0 {
|
||||
if rawTagHash != 0 && attr.Hash == Type {
|
||||
rawTagMediatype = parse.Copy(val)
|
||||
}
|
||||
|
||||
// default attribute values can be omitted
|
||||
if !o.KeepDefaultAttrVals && (attr.Hash == Type && (t.Hash == Script && jsMimetypes[string(val)] ||
|
||||
t.Hash == Style && bytes.Equal(val, []byte("text/css")) ||
|
||||
t.Hash == Link && bytes.Equal(val, []byte("text/css")) ||
|
||||
t.Hash == Input && bytes.Equal(val, []byte("text")) ||
|
||||
t.Hash == Button && bytes.Equal(val, []byte("submit"))) ||
|
||||
attr.Hash == Language && t.Hash == Script ||
|
||||
attr.Hash == Method && bytes.Equal(val, []byte("get")) ||
|
||||
attr.Hash == Enctype && bytes.Equal(val, []byte("application/x-www-form-urlencoded")) ||
|
||||
attr.Hash == Colspan && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == Rowspan && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == Shape && bytes.Equal(val, []byte("rect")) ||
|
||||
attr.Hash == Span && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == Clear && bytes.Equal(val, []byte("none")) ||
|
||||
attr.Hash == Frameborder && bytes.Equal(val, []byte("1")) ||
|
||||
attr.Hash == Scrolling && bytes.Equal(val, []byte("auto")) ||
|
||||
attr.Hash == Valuetype && bytes.Equal(val, []byte("data")) ||
|
||||
attr.Hash == Media && t.Hash == Style && bytes.Equal(val, []byte("all"))) {
|
||||
continue
|
||||
}
|
||||
} else if len(attr.Text) > 2 && attr.Text[0] == 'o' && attr.Text[1] == 'n' {
|
||||
val = parse.TrimWhitespace(val)
|
||||
if len(val) >= 11 && parse.EqualFold(val[:11], jsSchemeBytes) {
|
||||
val = val[11:]
|
||||
}
|
||||
attrMinifyBuffer.Reset()
|
||||
if err := m.MinifyMimetype(jsMimeBytes, attrMinifyBuffer, buffer.NewReader(val), nil); err == nil {
|
||||
val = attrMinifyBuffer.Bytes()
|
||||
} else if err != minify.ErrNotExist {
|
||||
return err
|
||||
}
|
||||
if len(val) == 0 {
|
||||
continue
|
||||
}
|
||||
} else if attr.Traits&urlAttr != 0 { // anchors are already handled
|
||||
val = parse.TrimWhitespace(val)
|
||||
if 5 < len(val) {
|
||||
if parse.EqualFold(val[:4], httpBytes) {
|
||||
if val[4] == ':' {
|
||||
if m.URL != nil && m.URL.Scheme == "http" {
|
||||
val = val[5:]
|
||||
} else {
|
||||
parse.ToLower(val[:4])
|
||||
}
|
||||
} else if (val[4] == 's' || val[4] == 'S') && val[5] == ':' {
|
||||
if m.URL != nil && m.URL.Scheme == "https" {
|
||||
val = val[6:]
|
||||
} else {
|
||||
parse.ToLower(val[:5])
|
||||
|
||||
if attr.Hash == Style {
|
||||
// CSS minifier for attribute inline code
|
||||
val = parse.TrimWhitespace(val)
|
||||
attrMinifyBuffer.Reset()
|
||||
if err := m.MinifyMimetype(cssMimeBytes, attrMinifyBuffer, buffer.NewReader(val), inlineParams); err == nil {
|
||||
val = attrMinifyBuffer.Bytes()
|
||||
} else if err != minify.ErrNotExist {
|
||||
return err
|
||||
}
|
||||
if len(val) == 0 {
|
||||
continue
|
||||
}
|
||||
} else if len(attr.Text) > 2 && attr.Text[0] == 'o' && attr.Text[1] == 'n' {
|
||||
// JS minifier for attribute inline code
|
||||
val = parse.TrimWhitespace(val)
|
||||
if len(val) >= 11 && parse.EqualFold(val[:11], jsSchemeBytes) {
|
||||
val = val[11:]
|
||||
}
|
||||
attrMinifyBuffer.Reset()
|
||||
if err := m.MinifyMimetype(jsMimeBytes, attrMinifyBuffer, buffer.NewReader(val), nil); err == nil {
|
||||
val = attrMinifyBuffer.Bytes()
|
||||
} else if err != minify.ErrNotExist {
|
||||
return err
|
||||
}
|
||||
if len(val) == 0 {
|
||||
continue
|
||||
}
|
||||
} else if attr.Traits&urlAttr != 0 { // anchors are already handled
|
||||
val = parse.TrimWhitespace(val)
|
||||
if 5 < len(val) {
|
||||
if parse.EqualFold(val[:4], httpBytes) {
|
||||
if val[4] == ':' {
|
||||
if m.URL != nil && m.URL.Scheme == "http" {
|
||||
val = val[5:]
|
||||
} else {
|
||||
parse.ToLower(val[:4])
|
||||
}
|
||||
} else if (val[4] == 's' || val[4] == 'S') && val[5] == ':' {
|
||||
if m.URL != nil && m.URL.Scheme == "https" {
|
||||
val = val[6:]
|
||||
} else {
|
||||
parse.ToLower(val[:5])
|
||||
}
|
||||
}
|
||||
} else if parse.EqualFold(val[:5], dataSchemeBytes) {
|
||||
val = minify.DataURI(m, val)
|
||||
}
|
||||
} else if parse.EqualFold(val[:5], dataSchemeBytes) {
|
||||
val = minify.DataURI(m, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -452,10 +464,10 @@ func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]st
|
|||
}
|
||||
|
||||
// use double quotes for RDFa attributes
|
||||
isXML := attr.Hash == html.Vocab || attr.Hash == html.Typeof || attr.Hash == html.Property || attr.Hash == html.Resource || attr.Hash == html.Prefix || attr.Hash == html.Content || attr.Hash == html.About || attr.Hash == html.Rev || attr.Hash == html.Datatype || attr.Hash == html.Inlist
|
||||
isXML := attr.Hash == Vocab || attr.Hash == Typeof || attr.Hash == Property || attr.Hash == Resource || attr.Hash == Prefix || attr.Hash == Content || attr.Hash == About || attr.Hash == Rev || attr.Hash == Datatype || attr.Hash == Inlist
|
||||
|
||||
// no quotes if possible, else prefer single or double depending on which occurs more often in value
|
||||
val = html.EscapeAttrVal(&attrByteBuffer, attr.AttrVal, val, isXML)
|
||||
val = html.EscapeAttrVal(&attrByteBuffer, attr.AttrVal, val, o.KeepQuotes || isXML)
|
||||
if _, err := w.Write(val); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
1513
vendor/github.com/tdewolff/minify/v2/html/table.go
generated
vendored
1513
vendor/github.com/tdewolff/minify/v2/html/table.go
generated
vendored
File diff suppressed because it is too large
Load diff
71
vendor/github.com/tdewolff/minify/v2/minify.go
generated
vendored
71
vendor/github.com/tdewolff/minify/v2/minify.go
generated
vendored
|
@ -1,21 +1,30 @@
|
|||
// Package minify relates MIME type to minifiers. Several minifiers are provided in the subpackages.
|
||||
package minify // import "github.com/tdewolff/minify"
|
||||
package minify
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"mime"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/tdewolff/parse/v2"
|
||||
"github.com/tdewolff/parse/v2/buffer"
|
||||
)
|
||||
|
||||
// Warning is used to report usage warnings such as using a deprecated feature
|
||||
var Warning = log.New(os.Stderr, "WARNING: ", 0)
|
||||
|
||||
// ErrNotExist is returned when no minifier exists for a given mimetype.
|
||||
var ErrNotExist = errors.New("minifier does not exist for mimetype")
|
||||
|
||||
|
@ -49,9 +58,55 @@ type cmdMinifier struct {
|
|||
func (c *cmdMinifier) Minify(_ *M, w io.Writer, r io.Reader, _ map[string]string) error {
|
||||
cmd := &exec.Cmd{}
|
||||
*cmd = *c.cmd // concurrency safety
|
||||
cmd.Stdout = w
|
||||
cmd.Stdin = r
|
||||
return cmd.Run()
|
||||
|
||||
var in, out *os.File
|
||||
for i, arg := range cmd.Args {
|
||||
if j := strings.Index(arg, "$in"); j != -1 {
|
||||
k := strings.IndexAny(arg[j+3:], " \r\n\t!\"#$&'()*;<=>?[\\]^`{|}")
|
||||
if k == -1 {
|
||||
k = len(arg)
|
||||
}
|
||||
|
||||
var err error
|
||||
if in, err = ioutil.TempFile("", "minify-in-*"+arg[j+3:k]); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Args[i] = arg[:j] + in.Name() + arg[k:]
|
||||
} else if j := strings.Index(arg, "$out"); j != -1 {
|
||||
k := strings.IndexAny(arg[j+4:], " \r\n\t!\"#$&'()*;<=>?[\\]^`{|}")
|
||||
if k == -1 {
|
||||
k = len(arg)
|
||||
}
|
||||
|
||||
var err error
|
||||
if out, err = ioutil.TempFile("", "minify-out-*"+arg[j+4:k]); err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Args[i] = arg[:j] + out.Name() + arg[k:]
|
||||
}
|
||||
}
|
||||
|
||||
if in == nil {
|
||||
cmd.Stdin = r
|
||||
} else if _, err := io.Copy(in, r); err != nil {
|
||||
return err
|
||||
}
|
||||
if out == nil {
|
||||
cmd.Stdout = w
|
||||
} else {
|
||||
defer io.Copy(w, out)
|
||||
}
|
||||
stderr := &bytes.Buffer{}
|
||||
cmd.Stderr = stderr
|
||||
|
||||
err := cmd.Run()
|
||||
if _, ok := err.(*exec.ExitError); ok {
|
||||
if stderr.Len() != 0 {
|
||||
err = fmt.Errorf("%s", stderr.String())
|
||||
}
|
||||
err = fmt.Errorf("command %s failed:\n%w", cmd.Path, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
@ -154,18 +209,16 @@ func (m *M) MinifyMimetype(mimetype []byte, w io.Writer, r io.Reader, params map
|
|||
m.mutex.RLock()
|
||||
defer m.mutex.RUnlock()
|
||||
|
||||
err := ErrNotExist
|
||||
if minifier, ok := m.literal[string(mimetype)]; ok { // string conversion is optimized away
|
||||
err = minifier.Minify(m, w, r, params)
|
||||
return minifier.Minify(m, w, r, params)
|
||||
} else {
|
||||
for _, minifier := range m.pattern {
|
||||
if minifier.pattern.Match(mimetype) {
|
||||
err = minifier.Minify(m, w, r, params)
|
||||
break
|
||||
return minifier.Minify(m, w, r, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
return ErrNotExist
|
||||
}
|
||||
|
||||
// Bytes minifies an array of bytes (safe for concurrent use). When an error occurs it return the original array and the error.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue