ref: f37e77f2d338cf876cfa637a662acd76f0f2009b
parent: 27af5a339a4d3c5712b5ed946a636a8c21916039
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Tue Apr 21 08:57:45 EDT 2020
Fix class collector when running with --minify Also add a related stresstest. Fixes #7161
--- 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,15 +987,24 @@
}
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", `
<div id="el1" class="a b c">Foo</div>
@@ -997,17 +1011,25 @@
Some text.
<div class="c d e" id="el2">Foo</div>
+
+<span class=z>FOO</span>
+
+ <a class="text-base hover:text-gradient inline-block px-3 pb-1 rounded lowercase" href="{{ .RelPermalink }}">{{ .Title }}</a>
+
+
`)
- 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",
@@ -1014,7 +1036,15 @@
"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 @@
}
}
`)
+
+ })
+
+ }
+}
+
+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", `
+<div class="c d e" id="el2">Foo</div>
+
+Some text.
+
+{{ $n := index (shuffle (seq 1 20)) 0 }}
+
+{{ "<span class=_a>Foo</span>" | strings.Repeat $n | safeHTML }}
+
+<div class="{{ .Title }}">
+ABC.
+</div>
+
+<div class="f"></div>
+
+{{ $n := index (shuffle (seq 1 5)) 0 }}
+
+{{ "<hr class=p-3>" | 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)
+ }
+
}
--- a/publisher/htmlElementsCollector.go
+++ b/publisher/htmlElementsCollector.go
@@ -87,11 +87,6 @@
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)
--- a/publisher/htmlElementsCollector_test.go
+++ b/publisher/htmlElementsCollector_test.go
@@ -51,6 +51,8 @@
{"duplicates", `<div class="b a b"></div>`, f("div", "a b", "")},
{"single quote", `<body class='b a'></body>`, f("body", "a b", "")},
{"no quote", `<body class=b id=myelement></body>`, f("body", "b", "myelement")},
+ // https://github.com/gohugoio/hugo/issues/7161
+ {"minified a href", `<a class="b a" href=/></a>`, f("a", "a b", "")},
{"AlpineJS bind 1", `<body>
<div x-bind:class="{