diff --git a/framework/h/app.go b/framework/h/app.go index 61a935a..2362348 100644 --- a/framework/h/app.go +++ b/framework/h/app.go @@ -3,9 +3,6 @@ package h import ( "context" "fmt" - "github.com/go-chi/chi/v5" - "github.com/maddalax/htmgo/framework/hx" - "github.com/maddalax/htmgo/framework/service" "log/slog" "net/http" "os" @@ -13,6 +10,10 @@ import ( "runtime" "strings" "time" + + "github.com/go-chi/chi/v5" + "github.com/maddalax/htmgo/framework/hx" + "github.com/maddalax/htmgo/framework/service" ) type RequestContext struct { @@ -214,9 +215,8 @@ func (app *App) start() { port := ":3000" slog.Info(fmt.Sprintf("Server started at localhost%s", port)) - err := http.ListenAndServe(port, app.Router) - if err != nil { + if err := http.ListenAndServe(port, app.Router); err != nil { // If we are in watch mode, just try to kill any processes holding that port // and try again if IsDevelopment() && IsWatchMode() { @@ -228,14 +228,16 @@ func (app *App) start() { cmd := exec.Command("bash", "-c", fmt.Sprintf("kill -9 $(lsof -ti%s)", port)) cmd.Run() } + time.Sleep(time.Millisecond * 50) - err = http.ListenAndServe(":3000", app.Router) - if err != nil { + + // Try to start server again + if err := http.ListenAndServe(port, app.Router); err != nil { + slog.Error("Failed to restart server", "error", err) panic(err) } - } else { - panic(err) } + panic(err) } } diff --git a/framework/h/attribute.go b/framework/h/attribute.go index 7cf8fd0..a9a9e72 100644 --- a/framework/h/attribute.go +++ b/framework/h/attribute.go @@ -2,9 +2,10 @@ package h import ( "fmt" + "strings" + "github.com/maddalax/htmgo/framework/hx" "github.com/maddalax/htmgo/framework/internal/datastructure" - "strings" ) type AttributeMap = map[string]any @@ -89,9 +90,7 @@ func Checked() Ren { } func Id(value string) Ren { - if strings.HasPrefix(value, "#") { - value = value[1:] - } + value = strings.TrimPrefix(value, "#") return Attribute("id", value) } @@ -193,6 +192,11 @@ func Class(value ...string) *AttributeR { return Attribute("class", MergeClasses(value...)) } +func ClassF(format string, args ...interface{}) *AttributeR { + atr := fmt.Sprintf(format, args...) + return Attribute("class", atr) +} + func ClassX(value string, m ClassMap) Ren { builder := strings.Builder{} builder.WriteString(value) diff --git a/framework/h/cache.go b/framework/h/cache.go index 92338cb..ad9260c 100644 --- a/framework/h/cache.go +++ b/framework/h/cache.go @@ -277,7 +277,7 @@ func (c *CachedNode) ClearExpired() { c.mutex.Lock() defer c.mutex.Unlock() deletedCount := 0 - if c.isByKey == true { + if c.isByKey { if c.byKeyCache != nil && c.byKeyExpiration != nil { for key := range c.byKeyCache { expir, ok := c.byKeyExpiration[key] @@ -303,7 +303,7 @@ func (c *CachedNode) ClearExpired() { } func (c *CachedNode) Render(ctx *RenderContext) { - if c.isByKey == true { + if c.isByKey { panic("CachedPerKey should not be rendered directly") } else { c.mutex.Lock() diff --git a/framework/h/tag.go b/framework/h/tag.go index 611fc55..5682e87 100644 --- a/framework/h/tag.go +++ b/framework/h/tag.go @@ -268,9 +268,7 @@ func TagF(tag string, format string, args ...interface{}) *Element { case *AttributeMapOrdered: children = append(children, d) case *ChildList: - for _, child := range d.Children { - children = append(children, child) - } + children = append(children, d.Children...) case *AttributeR: children = append(children, d) default: