aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/tdewolff/minify/js
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tdewolff/minify/js')
-rw-r--r--vendor/github.com/tdewolff/minify/js/js.go88
-rw-r--r--vendor/github.com/tdewolff/minify/js/js_test.go96
2 files changed, 184 insertions, 0 deletions
diff --git a/vendor/github.com/tdewolff/minify/js/js.go b/vendor/github.com/tdewolff/minify/js/js.go
new file mode 100644
index 0000000..1f6c0b8
--- /dev/null
+++ b/vendor/github.com/tdewolff/minify/js/js.go
@@ -0,0 +1,88 @@
+// Package js minifies ECMAScript5.1 following the specifications at http://www.ecma-international.org/ecma-262/5.1/.
+package js // import "github.com/tdewolff/minify/js"
+
+import (
+ "io"
+
+ "github.com/tdewolff/minify"
+ "github.com/tdewolff/parse"
+ "github.com/tdewolff/parse/js"
+)
+
+var (
+ spaceBytes = []byte(" ")
+ newlineBytes = []byte("\n")
+)
+
+////////////////////////////////////////////////////////////////
+
+// DefaultMinifier is the default minifier.
+var DefaultMinifier = &Minifier{}
+
+// Minifier is a JS minifier.
+type Minifier struct{}
+
+// Minify minifies JS data, it reads from r and writes to w.
+func Minify(m *minify.M, w io.Writer, r io.Reader, params map[string]string) error {
+ return DefaultMinifier.Minify(m, w, r, params)
+}
+
+// Minify minifies JS data, it reads from r and writes to w.
+func (o *Minifier) Minify(_ *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
+ prev := js.LineTerminatorToken
+ prevLast := byte(' ')
+ lineTerminatorQueued := false
+ whitespaceQueued := false
+
+ l := js.NewLexer(r)
+ defer l.Restore()
+
+ for {
+ tt, data := l.Next()
+ if tt == js.ErrorToken {
+ if l.Err() != io.EOF {
+ return l.Err()
+ }
+ return nil
+ } else if tt == js.LineTerminatorToken {
+ lineTerminatorQueued = true
+ } else if tt == js.WhitespaceToken {
+ whitespaceQueued = true
+ } else if tt == js.CommentToken {
+ if len(data) > 5 && data[1] == '*' && data[2] == '!' {
+ if _, err := w.Write(data[:3]); err != nil {
+ return err
+ }
+ comment := parse.TrimWhitespace(parse.ReplaceMultipleWhitespace(data[3 : len(data)-2]))
+ if _, err := w.Write(comment); err != nil {
+ return err
+ }
+ if _, err := w.Write(data[len(data)-2:]); err != nil {
+ return err
+ }
+ }
+ } else {
+ first := data[0]
+ if (prev == js.IdentifierToken || prev == js.NumericToken || prev == js.PunctuatorToken || prev == js.StringToken || prev == js.RegexpToken) &&
+ (tt == js.IdentifierToken || tt == js.NumericToken || tt == js.StringToken || tt == js.PunctuatorToken || tt == js.RegexpToken) {
+ if lineTerminatorQueued && (prev != js.PunctuatorToken || prevLast == '}' || prevLast == ']' || prevLast == ')' || prevLast == '+' || prevLast == '-' || prevLast == '"' || prevLast == '\'') &&
+ (tt != js.PunctuatorToken || first == '{' || first == '[' || first == '(' || first == '+' || first == '-' || first == '!' || first == '~') {
+ if _, err := w.Write(newlineBytes); err != nil {
+ return err
+ }
+ } else if whitespaceQueued && (prev != js.StringToken && prev != js.PunctuatorToken && tt != js.PunctuatorToken || (prevLast == '+' || prevLast == '-') && first == prevLast) {
+ if _, err := w.Write(spaceBytes); err != nil {
+ return err
+ }
+ }
+ }
+ if _, err := w.Write(data); err != nil {
+ return err
+ }
+ prev = tt
+ prevLast = data[len(data)-1]
+ lineTerminatorQueued = false
+ whitespaceQueued = false
+ }
+ }
+}
diff --git a/vendor/github.com/tdewolff/minify/js/js_test.go b/vendor/github.com/tdewolff/minify/js/js_test.go
new file mode 100644
index 0000000..816ce90
--- /dev/null
+++ b/vendor/github.com/tdewolff/minify/js/js_test.go
@@ -0,0 +1,96 @@
+package js // import "github.com/tdewolff/minify/js"
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/tdewolff/minify"
+ "github.com/tdewolff/test"
+)
+
+func TestJS(t *testing.T) {
+ jsTests := []struct {
+ js string
+ expected string
+ }{
+ {"/*comment*/", ""},
+ {"// comment\na", "a"},
+ {"/*! bang comment */", "/*!bang comment*/"},
+ {"function x(){}", "function x(){}"},
+ {"function x(a, b){}", "function x(a,b){}"},
+ {"a b", "a b"},
+ {"a\n\nb", "a\nb"},
+ {"a// comment\nb", "a\nb"},
+ {"''\na", "''\na"},
+ {"''\n''", "''\n''"},
+ {"]\n0", "]\n0"},
+ {"a\n{", "a\n{"},
+ {";\na", ";a"},
+ {",\na", ",a"},
+ {"}\na", "}\na"},
+ {"+\na", "+\na"},
+ {"+\n(", "+\n("},
+ {"+\n\"\"", "+\n\"\""},
+ {"a + ++b", "a+ ++b"}, // JSMin caution
+ {"var a=/\\s?auto?\\s?/i\nvar", "var a=/\\s?auto?\\s?/i\nvar"}, // #14
+ {"var a=0\n!function(){}", "var a=0\n!function(){}"}, // #107
+ {"function(){}\n\"string\"", "function(){}\n\"string\""}, // #109
+ {"false\n\"string\"", "false\n\"string\""}, // #109
+ {"`\n", "`"}, // go fuzz
+ {"a\n~b", "a\n~b"}, // #132
+ }
+
+ m := minify.New()
+ for _, tt := range jsTests {
+ t.Run(tt.js, func(t *testing.T) {
+ r := bytes.NewBufferString(tt.js)
+ w := &bytes.Buffer{}
+ err := Minify(m, w, r, nil)
+ test.Minify(t, tt.js, err, w.String(), tt.expected)
+ })
+ }
+}
+
+func TestReaderErrors(t *testing.T) {
+ r := test.NewErrorReader(0)
+ w := &bytes.Buffer{}
+ m := minify.New()
+ err := Minify(m, w, r, nil)
+ test.T(t, err, test.ErrPlain, "return error at first read")
+}
+
+func TestWriterErrors(t *testing.T) {
+ errorTests := []struct {
+ js string
+ n []int
+ }{
+ {"a\n{5 5", []int{0, 1, 4}},
+ {`/*!comment*/`, []int{0, 1, 2}},
+ {"false\n\"string\"", []int{1}}, // #109
+ }
+
+ m := minify.New()
+ for _, tt := range errorTests {
+ for _, n := range tt.n {
+ t.Run(fmt.Sprint(tt.js, " ", tt.n), func(t *testing.T) {
+ r := bytes.NewBufferString(tt.js)
+ w := test.NewErrorWriter(n)
+ err := Minify(m, w, r, nil)
+ test.T(t, err, test.ErrPlain)
+ })
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+func ExampleMinify() {
+ m := minify.New()
+ m.AddFunc("text/javascript", Minify)
+
+ if err := m.Minify("text/javascript", os.Stdout, os.Stdin); err != nil {
+ panic(err)
+ }
+}