diff --git a/hugolib/site_test.go b/hugolib/site_test.go index e404d80a4..3116113c0 100644 --- a/hugolib/site_test.go +++ b/hugolib/site_test.go @@ -14,11 +14,16 @@ package hugolib import ( + "encoding/json" "fmt" + "io/ioutil" + "os" "path/filepath" "strings" "testing" + "github.com/gohugoio/hugo/publisher" + "github.com/spf13/viper" "github.com/markbates/inflect" @@ -982,39 +987,64 @@ func TestRefIssues(t *testing.T) { } func TestClassCollector(t *testing.T) { - b := newTestSitesBuilder(t) - b.WithConfigFile("toml", ` + + for _, minify := range []bool{false, true} { + t.Run(fmt.Sprintf("minify-%t", minify), func(t *testing.T) { + statsFilename := "hugo_stats.json" + defer os.Remove(statsFilename) + + b := newTestSitesBuilder(t) + b.WithConfigFile("toml", fmt.Sprintf(` + + +minify = %t [build] writeStats = true -`) +`, minify)) - b.WithTemplates("index.html", ` + b.WithTemplates("index.html", `
Foo
Some text.
Foo
+ +FOO + + {{ .Title }} + + `) - b.WithContent("p1.md", "") + b.WithContent("p1.md", "") - b.Build(BuildCfg{}) + b.Build(BuildCfg{}) - b.AssertFileContent("hugo_stats.json", ` -{ + b.AssertFileContent("hugo_stats.json", ` + { "htmlElements": { "tags": [ - "div" + "a", + "div", + "span" ], "classes": [ "a", "b", "c", "d", - "e" + "e", + "hover:text-gradient", + "inline-block", + "lowercase", + "pb-1", + "px-3", + "rounded", + "text-base", + "z" ], "ids": [ "el1", @@ -1023,4 +1053,78 @@ Some text. } } `) + + }) + + } +} + +func TestClassCollectorStress(t *testing.T) { + statsFilename := "hugo_stats.json" + defer os.Remove(statsFilename) + + b := newTestSitesBuilder(t) + b.WithConfigFile("toml", ` + +disableKinds = ["home", "section", "taxonomy", "taxonomyTerm" ] + +[languages] +[languages.en] +[languages.nb] +[languages.no] +[languages.sv] + + +[build] + writeStats = true + +`) + + b.WithTemplates("_default/single.html", ` +
Foo
+ +Some text. + +{{ $n := index (shuffle (seq 1 20)) 0 }} + +{{ "Foo" | strings.Repeat $n | safeHTML }} + +
+ABC. +
+ +
+ +{{ $n := index (shuffle (seq 1 5)) 0 }} + +{{ "
" | safeHTML }} + +`) + + for _, lang := range []string{"en", "nb", "no", "sv"} { + + for i := 100; i <= 999; i++ { + b.WithContent(fmt.Sprintf("p%d.%s.md", i, lang), fmt.Sprintf("---\ntitle: p%s%d\n---", lang, i)) + } + } + + b.Build(BuildCfg{}) + + contentMem := b.FileContent(statsFilename) + cb, err := ioutil.ReadFile(statsFilename) + b.Assert(err, qt.IsNil) + contentFile := string(cb) + + for _, content := range []string{contentMem, contentFile} { + + stats := &publisher.PublishStats{} + b.Assert(json.Unmarshal([]byte(content), stats), qt.IsNil) + + els := stats.HTMLElements + + b.Assert(els.Classes, qt.HasLen, 3606) // (4 * 900) + 4 +2 + b.Assert(els.Tags, qt.HasLen, 8) + b.Assert(els.IDs, qt.HasLen, 1) + } + } diff --git a/publisher/htmlElementsCollector.go b/publisher/htmlElementsCollector.go index c6e0d3f0f..6166c49ad 100644 --- a/publisher/htmlElementsCollector.go +++ b/publisher/htmlElementsCollector.go @@ -87,11 +87,6 @@ func (w *cssClassCollectorWriter) Write(p []byte) (n int, err error) { if w.isCollecting { for ; i < len(p); i++ { b := p[i] - if !w.inQuote && b == '/' { - // End element, we don't care about those. - w.endCollecting(true) - break - } w.toggleIfQuote(b) if !w.inQuote && b == '>' { w.endCollecting(false) diff --git a/publisher/htmlElementsCollector_test.go b/publisher/htmlElementsCollector_test.go index 3ef159d8b..fe3876ae6 100644 --- a/publisher/htmlElementsCollector_test.go +++ b/publisher/htmlElementsCollector_test.go @@ -51,6 +51,8 @@ func TestClassCollector(t *testing.T) { {"duplicates", `
`, f("div", "a b", "")}, {"single quote", ``, f("body", "a b", "")}, {"no quote", ``, f("body", "b", "myelement")}, + // https://github.com/gohugoio/hugo/issues/7161 + {"minified a href", ``, f("a", "a b", "")}, {"AlpineJS bind 1", `