webtools/cmds/gotemplate/main.go

93 lines
2.1 KiB
Go
Raw Normal View History

2025-09-26 07:28:30 +00:00
//go:build js
package main
import (
"bytes"
"encoding/json"
"syscall/js"
"text/template"
)
func main() {
regenChan := make(chan struct{})
go executeTemplate(regenChan)
eventListener := func(this js.Value, args []js.Value) interface{} {
ev := args[0]
ev.Call("preventDefault")
regenChan <- struct{}{}
return nil
}
querySelector("#template").Call("addEventListener", "keyup", js.FuncOf(eventListener))
querySelector("#data").Call("addEventListener", "keyup", js.FuncOf(eventListener))
regenChan <- struct{}{}
<-make(chan struct{})
}
func executeTemplate(regenChan chan struct{}) {
templateEl := querySelector("#template")
dataEl := querySelector("#data")
outputEl := querySelector("#output")
tmplMessageEl := querySelector("#template-message")
dataMessageEl := querySelector("#data-message")
displayErrors := func(dataErr error, tmplErr error) {
if dataErr != nil {
dataMessageEl.Set("innerText", dataErr.Error())
} else {
dataMessageEl.Set("innerText", "")
}
if tmplErr != nil {
tmplMessageEl.Set("innerText", tmplErr.Error())
} else {
tmplMessageEl.Set("innerText", "")
}
}
var templateSource string
var tmpl *template.Template
setTemplateSource := func(newTemplateSource string) (*template.Template, error) {
if tmpl == nil || templateSource != newTemplateSource {
newTmpl := template.New("")
if _, err := newTmpl.Parse(newTemplateSource); err != nil {
return nil, err
}
tmpl = newTmpl
}
return tmpl, nil
}
var outBuf bytes.Buffer
for range regenChan {
templateValue := templateEl.Get("value").String()
dataValue := dataEl.Get("value").String()
var dataJson interface{}
dataErr := json.Unmarshal([]byte(dataValue), &dataJson)
tmplInst, tmplErr := setTemplateSource(templateValue)
if dataErr != nil || tmplErr != nil {
displayErrors(dataErr, tmplErr)
continue
}
outBuf.Reset()
if err := tmplInst.Execute(&outBuf, dataJson); err != nil {
displayErrors(nil, err)
continue
}
outputEl.Set("innerText", outBuf.String())
displayErrors(nil, nil)
}
}
func querySelector(query string) js.Value {
return js.Global().Get("document").Call("querySelector", query)
}