mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
parent
fe60b7d9e4
commit
c03ea2b660
2 changed files with 18 additions and 17 deletions
|
@ -14,9 +14,10 @@
|
||||||
package publisher
|
package publisher
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/helpers"
|
"github.com/gohugoio/hugo/helpers"
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
yaml "gopkg.in/yaml.v2"
|
|
||||||
|
|
||||||
"bytes"
|
"bytes"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -196,7 +197,10 @@ func isQuote(b byte) bool {
|
||||||
return b == '"' || b == '\''
|
return b == '"' || b == '\''
|
||||||
}
|
}
|
||||||
|
|
||||||
var htmlJsonFixer = strings.NewReplacer(", ", "\n")
|
var (
|
||||||
|
htmlJsonFixer = strings.NewReplacer(", ", "\n")
|
||||||
|
jsonAttrRe = regexp.MustCompile(`'?(.*?)'?:.*`)
|
||||||
|
)
|
||||||
|
|
||||||
func parseHTMLElement(elStr string) (el htmlElement) {
|
func parseHTMLElement(elStr string) (el htmlElement) {
|
||||||
elStr = strings.TrimSpace(elStr)
|
elStr = strings.TrimSpace(elStr)
|
||||||
|
@ -225,27 +229,15 @@ func parseHTMLElement(elStr string) (el htmlElement) {
|
||||||
val := strings.TrimSpace(a.Val)
|
val := strings.TrimSpace(a.Val)
|
||||||
if strings.Contains(key, "class") && strings.HasPrefix(val, "{") {
|
if strings.Contains(key, "class") && strings.HasPrefix(val, "{") {
|
||||||
// This looks like a Vue or AlpineJS class binding.
|
// This looks like a Vue or AlpineJS class binding.
|
||||||
// Try to unmarshal it as YAML and pull the keys.
|
|
||||||
// This may look odd, as the source is (probably) JS (JSON), but the YAML
|
|
||||||
// parser is much more lenient with simple JS input, it seems.
|
|
||||||
m := make(map[string]interface{})
|
|
||||||
val = htmlJsonFixer.Replace(strings.Trim(val, "{}"))
|
val = htmlJsonFixer.Replace(strings.Trim(val, "{}"))
|
||||||
// Remove leading space to make it look like YAML.
|
|
||||||
lines := strings.Split(val, "\n")
|
lines := strings.Split(val, "\n")
|
||||||
for i, l := range lines {
|
for i, l := range lines {
|
||||||
lines[i] = strings.TrimSpace(l)
|
lines[i] = strings.TrimSpace(l)
|
||||||
}
|
}
|
||||||
val = strings.Join(lines, "\n")
|
val = strings.Join(lines, "\n")
|
||||||
err := yaml.Unmarshal([]byte(val), &m)
|
val = jsonAttrRe.ReplaceAllString(val, "$1")
|
||||||
if err == nil {
|
el.Classes = append(el.Classes, strings.Fields(val)...)
|
||||||
for k := range m {
|
|
||||||
el.Classes = append(el.Classes, strings.Fields(k)...)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Just insert the raw values. This is used for CSS class pruning
|
|
||||||
// so, it's important not to leave out values that may be a CSS class.
|
|
||||||
el.Classes = append(el.Classes, strings.Fields(val)...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,15 @@ func TestClassCollector(t *testing.T) {
|
||||||
{"Alpine bind 4", `<div x-bind:class="{ 'text-gray-800': !checked,
|
{"Alpine bind 4", `<div x-bind:class="{ 'text-gray-800': !checked,
|
||||||
'text-white': checked }"></div>`, f("div", "text-gray-800 text-white", "")},
|
'text-white': checked }"></div>`, f("div", "text-gray-800 text-white", "")},
|
||||||
|
|
||||||
|
{"Alpine bind 5", `<a x-bind:class="{
|
||||||
|
'text-a': a && b,
|
||||||
|
'text-b': !a && b || c,
|
||||||
|
'pl-3': a === 1,
|
||||||
|
pl-2: b == 3,
|
||||||
|
'text-gray-600': (a > 1)
|
||||||
|
|
||||||
|
}" class="block w-36 cursor-pointer pr-3 no-underline capitalize"></a>`, f("a", "block capitalize cursor-pointer no-underline pl-2 pl-3 pr-3 text-a text-b text-gray-600 w-36", "")},
|
||||||
|
|
||||||
{"Vue bind", `<div v-bind:class="{ active: isActive }"></div>`, f("div", "active", "")},
|
{"Vue bind", `<div v-bind:class="{ active: isActive }"></div>`, f("div", "active", "")},
|
||||||
} {
|
} {
|
||||||
c.Run(test.name, func(c *qt.C) {
|
c.Run(test.name, func(c *qt.C) {
|
||||||
|
|
Loading…
Reference in a new issue