diff --git a/bindings/js/go/minify.go b/bindings/js/go/minify.go index c24677823..b43c60df4 100644 --- a/bindings/js/go/minify.go +++ b/bindings/js/go/minify.go @@ -109,6 +109,18 @@ func parseOptions(opts *C.MinifyOptions) (minifyOptions, error) { }, nil } +func toSet(tags []string) map[string]struct{} { + if len(tags) == 0 { + return nil + } + + m := make(map[string]struct{}, len(tags)) + for _, t := range tags { + m[strings.ToLower(t)] = struct{}{} + } + return m +} + func newMinifier(opts minifyOptions) (*minify.M, error) { m := minify.New() @@ -125,6 +137,7 @@ func newMinifier(opts minifyOptions) (*minify.M, error) { KeepQuotes: opts.HTMLKeepQuotes, KeepSpecialComments: opts.HTMLKeepSpecialComments, KeepWhitespace: opts.HTMLKeepWhitespace, + PreserveWhitespaceTags: toSet(opts.PreserveWhitespaceTags), } jsMinifier := &js.Minifier{ Precision: opts.JSPrecision, diff --git a/html/html.go b/html/html.go index 938b794a4..5f1c26b54 100644 --- a/html/html.go +++ b/html/html.go @@ -5,6 +5,7 @@ import ( "bytes" "fmt" "io" + "strings" "github.com/tdewolff/minify/v2" "github.com/tdewolff/parse/v2" @@ -61,6 +62,7 @@ type Minifier struct { KeepQuotes bool KeepWhitespace bool TemplateDelims [2]string + PreserveWhitespaceTags map[string]struct{} } // Minify minifies HTML data, it reads from r and writes to w. @@ -68,6 +70,23 @@ func Minify(m *minify.M, w io.Writer, r io.Reader, params map[string]string) err return (&Minifier{}).Minify(m, w, r, params) } +func (o *Minifier) isWhitespaceTag(t Token) bool { + if o.PreserveWhitespaceTags == nil { + return false + } + + if t.TokenType != html.StartTagToken && t.TokenType != html.EndTagToken { + return false + } + + tag := strings.ToLower(string(t.Data)) + tag = strings.TrimPrefix(tag, "<") + tag = strings.TrimPrefix(tag, "\n foo\n bar\n", + "\n foo\n bar\n", + }, + { + "\n foo\n bar\n", + "foo\nbar", + }, + { + "
\n    foo\n    bar\n
", + "
\n    foo\n    bar\n
", + }, + } + + m := minify.New() + m.AddFunc("text/css", css.Minify) + + htmlMinifier := &Minifier{ + PreserveWhitespaceTags: map[string]struct{}{ + "custom-component": {}, + }, + } + + for _, tt := range htmlTests { + t.Run(tt.html, func(t *testing.T) { + r := bytes.NewBufferString(tt.html) + w := &bytes.Buffer{} + err := htmlMinifier.Minify(m, w, r, nil) + test.Minify(t, tt.html, err, w.String(), tt.expected) + }) + } +} + func TestMinifyErrorPropagation(t *testing.T) { errorTests := []struct { html string