htmgo/framework/h/lifecycle.go

198 lines
4.8 KiB
Go
Raw Normal View History

package h
import (
"fmt"
2024-09-21 03:59:07 +00:00
"github.com/maddalax/htmgo/framework/hx"
2024-09-22 15:46:38 +00:00
"github.com/maddalax/htmgo/framework/internal/util"
)
type LifeCycle struct {
2024-09-21 03:59:07 +00:00
handlers map[hx.Event][]Command
}
func NewLifeCycle() *LifeCycle {
return &LifeCycle{
2024-09-21 03:59:07 +00:00
handlers: make(map[hx.Event][]Command),
}
}
2024-09-21 03:59:07 +00:00
func validateCommands(cmds []Command) {
for _, cmd := range cmds {
switch t := cmd.(type) {
2024-09-22 15:46:38 +00:00
case SimpleJsCommand:
break
case ComplexJsCommand:
2024-09-21 03:59:07 +00:00
break
case *AttributeMap:
break
case *Element:
panic(fmt.Sprintf("element is not allowed in lifecycle events. Got: %v", t))
default:
panic(fmt.Sprintf("type is not allowed in lifecycle events. Got: %v", t))
}
}
}
func (l *LifeCycle) OnEvent(event hx.Event, cmd ...Command) *LifeCycle {
validateCommands(cmd)
if l.handlers[event] == nil {
2024-09-21 03:59:07 +00:00
l.handlers[event] = []Command{}
}
2024-09-21 03:59:07 +00:00
l.handlers[event] = append(l.handlers[event], cmd...)
return l
}
2024-09-21 03:59:07 +00:00
func (l *LifeCycle) BeforeRequest(cmd ...Command) *LifeCycle {
l.OnEvent(hx.BeforeRequestEvent, cmd...)
return l
}
2024-09-21 03:59:07 +00:00
func OnLoad(cmd ...Command) *LifeCycle {
return NewLifeCycle().OnEvent(hx.LoadEvent, cmd...)
}
func OnAfterSwap(cmd ...Command) *LifeCycle {
return NewLifeCycle().OnEvent(hx.AfterSwapEvent, cmd...)
}
func OnTrigger(trigger string, cmd ...Command) *LifeCycle {
return NewLifeCycle().OnEvent(hx.NewStringTrigger(trigger).ToString(), cmd...)
}
func OnClick(cmd ...Command) *LifeCycle {
return NewLifeCycle().OnEvent(hx.ClickEvent, cmd...)
}
func OnEvent(event hx.Event, cmd ...Command) *LifeCycle {
return NewLifeCycle().OnEvent(event, cmd...)
}
2024-09-21 03:59:07 +00:00
func BeforeRequest(cmd ...Command) *LifeCycle {
return NewLifeCycle().BeforeRequest(cmd...)
}
2024-09-21 03:59:07 +00:00
func AfterRequest(cmd ...Command) *LifeCycle {
return NewLifeCycle().AfterRequest(cmd...)
}
2024-09-21 03:59:07 +00:00
func OnMutationError(cmd ...Command) *LifeCycle {
return NewLifeCycle().OnMutationError(cmd...)
}
2024-09-21 03:59:07 +00:00
func (l *LifeCycle) AfterRequest(cmd ...Command) *LifeCycle {
l.OnEvent(hx.AfterRequestEvent, cmd...)
return l
}
2024-09-21 03:59:07 +00:00
func (l *LifeCycle) OnMutationError(cmd ...Command) *LifeCycle {
l.OnEvent(hx.OnMutationErrorEvent, cmd...)
return l
}
2024-09-21 03:59:07 +00:00
type Command = Ren
2024-09-22 15:46:38 +00:00
type SimpleJsCommand struct {
Command string
}
2024-09-22 15:46:38 +00:00
type ComplexJsCommand struct {
Command string
TempFuncName string
2024-09-21 03:59:07 +00:00
}
2024-09-22 15:46:38 +00:00
func SetText(text string) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.innerText = '%s'", text)}
}
2024-09-22 15:46:38 +00:00
func Increment(amount int) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.innerText = parseInt(this.innerText) + %d", amount)}
}
2024-09-22 15:46:38 +00:00
func SetInnerHtml(r Ren) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.innerHTML = `%s`", Render(r))}
}
2024-09-22 15:46:38 +00:00
func SetOuterHtml(r Ren) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.outerHTML = `%s`", Render(r))}
}
2024-09-22 15:46:38 +00:00
func AddAttribute(name, value string) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.setAttribute('%s', '%s')", name, value)}
}
2024-09-22 15:46:38 +00:00
func SetDisabled(disabled bool) SimpleJsCommand {
if disabled {
return AddAttribute("disabled", "true")
} else {
return RemoveAttribute("disabled")
}
}
2024-09-22 15:46:38 +00:00
func RemoveAttribute(name string) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.removeAttribute('%s')", name)}
}
2024-09-22 15:46:38 +00:00
func AddClass(class string) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.classList.add('%s')", class)}
}
2024-09-22 15:46:38 +00:00
func RemoveClass(class string) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.classList.remove('%s')", class)}
}
2024-09-22 15:46:38 +00:00
func ToggleClass(class string) SimpleJsCommand {
2024-09-19 23:11:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("this.classList.toggle('%s')", class)}
}
2024-09-22 15:46:38 +00:00
func ToggleClassOnElement(selector, class string) ComplexJsCommand {
// language=JavaScript
return EvalJs(fmt.Sprintf(`
var el = document.querySelector('%s');
if(el) { el.classList.toggle('%s'); }`,
))
}
2024-09-20 20:15:12 +00:00
2024-09-22 15:46:38 +00:00
func Alert(text string) SimpleJsCommand {
2024-09-20 20:15:12 +00:00
// language=JavaScript
2024-09-22 15:46:38 +00:00
return SimpleJsCommand{Command: fmt.Sprintf("alert('%s')", text)}
}
func EvalJs(js string) ComplexJsCommand {
name := fmt.Sprintf("__eval_%s", util.RandSeq(6))
return ComplexJsCommand{Command: js, TempFuncName: name}
}
func InjectScript(src string) ComplexJsCommand {
// language=JavaScript
return ComplexJsCommand{Command: fmt.Sprintf(`
2024-09-20 20:15:12 +00:00
var script = document.createElement('script');
script.src = '%s';
src.async = true;
document.head.appendChild(script);
`, src)}
}
2024-09-22 15:46:38 +00:00
func InjectScriptIfNotExist(src string) ComplexJsCommand {
// language=JavaScript
return EvalJs(fmt.Sprintf(`
if(!document.querySelector('script[src="%s"]')) {
var script = document.createElement('script');
script.src = '%s';
script.async = true;
document.head.appendChild(script);
}
`, src, src))
}