add support for complex raw js
This commit is contained in:
parent
59900b59ea
commit
789b9e9c7c
14 changed files with 4086 additions and 77 deletions
3901
framework/assets/dist/htmgo.js
vendored
3901
framework/assets/dist/htmgo.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -5,6 +5,7 @@ import "./htmxextensions/debug";
|
||||||
import "./htmxextensions/response-targets";
|
import "./htmxextensions/response-targets";
|
||||||
import "./htmxextensions/mutation-error";
|
import "./htmxextensions/mutation-error";
|
||||||
import "./htmxextensions/livereload"
|
import "./htmxextensions/livereload"
|
||||||
|
import "./htmxextensions/htmgo";
|
||||||
|
|
||||||
function watchUrl(callback: (oldUrl: string, newUrl: string) => void) {
|
function watchUrl(callback: (oldUrl: string, newUrl: string) => void) {
|
||||||
let lastUrl = window.location.href;
|
let lastUrl = window.location.href;
|
||||||
|
|
|
||||||
26
framework/assets/js/htmxextensions/htmgo.ts
Normal file
26
framework/assets/js/htmxextensions/htmgo.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import htmx from "htmx.org";
|
||||||
|
|
||||||
|
const evalFuncRegex = /__eval_[A-Za-z0-9]+\(\)/gm
|
||||||
|
|
||||||
|
htmx.defineExtension("htmgo", {
|
||||||
|
// @ts-ignore
|
||||||
|
onEvent: function (name, evt) {
|
||||||
|
if(name === "htmx:beforeCleanupElement" && evt.target) {
|
||||||
|
removeAssociatedScripts(evt.target as HTMLElement);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function removeAssociatedScripts(element: HTMLElement) {
|
||||||
|
const attributes = Array.from(element.attributes)
|
||||||
|
for (let attribute of attributes) {
|
||||||
|
const matches = attribute.value.match(evalFuncRegex) || []
|
||||||
|
for (let match of matches) {
|
||||||
|
const id = match.replace("()", "")
|
||||||
|
const ele = document.getElementById(id)
|
||||||
|
if(ele && ele.tagName === "SCRIPT") {
|
||||||
|
ele.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Partial struct {
|
type Partial struct {
|
||||||
|
|
@ -13,10 +12,6 @@ type Partial struct {
|
||||||
Root *Element
|
Root *Element
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Partial) Render(builder *strings.Builder) {
|
|
||||||
p.Root.Render(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Page struct {
|
type Page struct {
|
||||||
Root Ren
|
Root Ren
|
||||||
HttpMethod string
|
HttpMethod string
|
||||||
|
|
|
||||||
11
framework/h/extensions.go
Normal file
11
framework/h/extensions.go
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
package h
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
func BaseExtensions() string {
|
||||||
|
extensions := []string{"path-deps", "response-targets", "mutation-error", "htmgo"}
|
||||||
|
if IsDevelopment() {
|
||||||
|
extensions = append(extensions, "livereload")
|
||||||
|
}
|
||||||
|
return strings.Join(extensions, ", ")
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ package h
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/maddalax/htmgo/framework/hx"
|
"github.com/maddalax/htmgo/framework/hx"
|
||||||
"strings"
|
"github.com/maddalax/htmgo/framework/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LifeCycle struct {
|
type LifeCycle struct {
|
||||||
|
|
@ -19,7 +19,9 @@ func NewLifeCycle() *LifeCycle {
|
||||||
func validateCommands(cmds []Command) {
|
func validateCommands(cmds []Command) {
|
||||||
for _, cmd := range cmds {
|
for _, cmd := range cmds {
|
||||||
switch t := cmd.(type) {
|
switch t := cmd.(type) {
|
||||||
case JsCommand:
|
case SimpleJsCommand:
|
||||||
|
break
|
||||||
|
case ComplexJsCommand:
|
||||||
break
|
break
|
||||||
case *AttributeMap:
|
case *AttributeMap:
|
||||||
break
|
break
|
||||||
|
|
@ -92,40 +94,41 @@ func (l *LifeCycle) OnMutationError(cmd ...Command) *LifeCycle {
|
||||||
|
|
||||||
type Command = Ren
|
type Command = Ren
|
||||||
|
|
||||||
type JsCommand struct {
|
type SimpleJsCommand struct {
|
||||||
Command string
|
Command string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j JsCommand) Render(builder *strings.Builder) {
|
type ComplexJsCommand struct {
|
||||||
builder.WriteString(j.Command)
|
Command string
|
||||||
|
TempFuncName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetText(text string) JsCommand {
|
func SetText(text string) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.innerText = '%s'", text)}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.innerText = '%s'", text)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Increment(amount int) JsCommand {
|
func Increment(amount int) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.innerText = parseInt(this.innerText) + %d", amount)}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.innerText = parseInt(this.innerText) + %d", amount)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetInnerHtml(r Ren) JsCommand {
|
func SetInnerHtml(r Ren) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.innerHTML = `%s`", Render(r))}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.innerHTML = `%s`", Render(r))}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetOuterHtml(r Ren) JsCommand {
|
func SetOuterHtml(r Ren) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.outerHTML = `%s`", Render(r))}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.outerHTML = `%s`", Render(r))}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddAttribute(name, value string) JsCommand {
|
func AddAttribute(name, value string) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.setAttribute('%s', '%s')", name, value)}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.setAttribute('%s', '%s')", name, value)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetDisabled(disabled bool) JsCommand {
|
func SetDisabled(disabled bool) SimpleJsCommand {
|
||||||
if disabled {
|
if disabled {
|
||||||
return AddAttribute("disabled", "true")
|
return AddAttribute("disabled", "true")
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -133,36 +136,62 @@ func SetDisabled(disabled bool) JsCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveAttribute(name string) JsCommand {
|
func RemoveAttribute(name string) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.removeAttribute('%s')", name)}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.removeAttribute('%s')", name)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddClass(class string) JsCommand {
|
func AddClass(class string) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.classList.add('%s')", class)}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.classList.add('%s')", class)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveClass(class string) JsCommand {
|
func RemoveClass(class string) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("this.classList.remove('%s')", class)}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.classList.remove('%s')", class)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Alert(text string) JsCommand {
|
func ToggleClass(class string) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf("alert('%s')", text)}
|
return SimpleJsCommand{Command: fmt.Sprintf("this.classList.toggle('%s')", class)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func EvalJs(js string) JsCommand {
|
func ToggleClassOnElement(selector, class string) ComplexJsCommand {
|
||||||
return JsCommand{Command: js}
|
// language=JavaScript
|
||||||
|
return EvalJs(fmt.Sprintf(`
|
||||||
|
var el = document.querySelector('%s');
|
||||||
|
if(el) { el.classList.toggle('%s'); }`,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
func InjectScript(src string) JsCommand {
|
func Alert(text string) SimpleJsCommand {
|
||||||
// language=JavaScript
|
// language=JavaScript
|
||||||
return JsCommand{Command: fmt.Sprintf(`
|
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(`
|
||||||
var script = document.createElement('script');
|
var script = document.createElement('script');
|
||||||
script.src = '%s';
|
script.src = '%s';
|
||||||
src.async = true;
|
src.async = true;
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
`, src)}
|
`, src)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Ren interface {
|
type Ren interface {
|
||||||
Render(builder *strings.Builder)
|
Render(context *RenderContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
func Render(node Ren) string {
|
func Render(node Ren) string {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
builder := &strings.Builder{}
|
builder := &strings.Builder{}
|
||||||
node.Render(builder)
|
context := &RenderContext{
|
||||||
|
builder: builder,
|
||||||
|
}
|
||||||
|
node.Render(context)
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
fmt.Printf("render took %d microseconds\n", duration.Microseconds())
|
fmt.Printf("render took %d microseconds\n", duration.Microseconds())
|
||||||
return builder.String()
|
return builder.String()
|
||||||
|
|
|
||||||
|
|
@ -6,15 +6,30 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (node *Element) Render(builder *strings.Builder) {
|
type RenderContext struct {
|
||||||
|
builder *strings.Builder
|
||||||
|
scripts []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ctx *RenderContext) AddScript(funcName string, body string) {
|
||||||
|
script := fmt.Sprintf(`
|
||||||
|
<script id="%s">
|
||||||
|
function %s() {
|
||||||
|
%s
|
||||||
|
}
|
||||||
|
</script>`, funcName, funcName, body)
|
||||||
|
ctx.scripts = append(ctx.scripts, script)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *Element) Render(context *RenderContext) {
|
||||||
// some elements may not have a tag, such as a Fragment
|
// some elements may not have a tag, such as a Fragment
|
||||||
|
|
||||||
if node.tag != "" {
|
if node.tag != "" {
|
||||||
builder.WriteString("<" + node.tag)
|
context.builder.WriteString("<" + node.tag)
|
||||||
builder.WriteString(" ")
|
context.builder.WriteString(" ")
|
||||||
|
|
||||||
for name, value := range node.attributes {
|
for name, value := range node.attributes {
|
||||||
NewAttribute(name, value).Render(builder)
|
NewAttribute(name, value).Render(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,15 +50,15 @@ func (node *Element) Render(builder *strings.Builder) {
|
||||||
for _, child := range node.children {
|
for _, child := range node.children {
|
||||||
switch child.(type) {
|
switch child.(type) {
|
||||||
case *AttributeMap:
|
case *AttributeMap:
|
||||||
child.Render(builder)
|
child.Render(context)
|
||||||
case *LifeCycle:
|
case *LifeCycle:
|
||||||
child.Render(builder)
|
child.Render(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// close the tag
|
// close the tag
|
||||||
if node.tag != "" {
|
if node.tag != "" {
|
||||||
builder.WriteString(">")
|
context.builder.WriteString(">")
|
||||||
}
|
}
|
||||||
|
|
||||||
// render the children elements that are not attributes
|
// render the children elements that are not attributes
|
||||||
|
|
@ -54,64 +69,88 @@ func (node *Element) Render(builder *strings.Builder) {
|
||||||
case *LifeCycle:
|
case *LifeCycle:
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
child.Render(builder)
|
child.Render(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.tag != "" {
|
if node.tag != "" {
|
||||||
builder.WriteString("</" + node.tag + ">")
|
renderScripts(context)
|
||||||
|
context.builder.WriteString("</" + node.tag + ">")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AttributeR) Render(builder *strings.Builder) {
|
func renderScripts(context *RenderContext) {
|
||||||
builder.WriteString(fmt.Sprintf(`%s="%s"`, a.Name, a.Value))
|
for _, script := range context.scripts {
|
||||||
|
context.builder.WriteString(script)
|
||||||
|
}
|
||||||
|
context.scripts = []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TextContent) Render(builder *strings.Builder) {
|
func (a *AttributeR) Render(context *RenderContext) {
|
||||||
builder.WriteString(t.Content)
|
context.builder.WriteString(fmt.Sprintf(`%s="%s"`, a.Name, a.Value))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RawContent) Render(builder *strings.Builder) {
|
func (t *TextContent) Render(context *RenderContext) {
|
||||||
builder.WriteString(r.Content)
|
context.builder.WriteString(t.Content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ChildList) Render(builder *strings.Builder) {
|
func (r *RawContent) Render(context *RenderContext) {
|
||||||
|
context.builder.WriteString(r.Content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ChildList) Render(context *RenderContext) {
|
||||||
for _, child := range c.Children {
|
for _, child := range c.Children {
|
||||||
child.Render(builder)
|
child.Render(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *AttributeMap) Render(builder *strings.Builder) {
|
func (j SimpleJsCommand) Render(context *RenderContext) {
|
||||||
|
context.builder.WriteString(j.Command)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j ComplexJsCommand) Render(context *RenderContext) {
|
||||||
|
context.builder.WriteString(j.Command)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Partial) Render(context *RenderContext) {
|
||||||
|
p.Root.Render(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *AttributeMap) Render(context *RenderContext) {
|
||||||
m2 := m.ToMap()
|
m2 := m.ToMap()
|
||||||
|
|
||||||
for k, v := range m2 {
|
for k, v := range m2 {
|
||||||
builder.WriteString(" ")
|
context.builder.WriteString(" ")
|
||||||
NewAttribute(k, v).Render(builder)
|
NewAttribute(k, v).Render(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LifeCycle) fromAttributeMap(event string, key string, value string, builder *strings.Builder) {
|
func (l *LifeCycle) fromAttributeMap(event string, key string, value string, context *RenderContext) {
|
||||||
|
|
||||||
if key == hx.GetAttr || key == hx.PatchAttr || key == hx.PostAttr {
|
if key == hx.GetAttr || key == hx.PatchAttr || key == hx.PostAttr {
|
||||||
TriggerString(hx.ToHtmxTriggerName(event)).Render(builder)
|
TriggerString(hx.ToHtmxTriggerName(event)).Render(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
Attribute(key, value).Render(builder)
|
Attribute(key, value).Render(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LifeCycle) Render(builder *strings.Builder) {
|
func (l *LifeCycle) Render(context *RenderContext) {
|
||||||
m := make(map[string]string)
|
m := make(map[string]string)
|
||||||
|
|
||||||
for event, commands := range l.handlers {
|
for event, commands := range l.handlers {
|
||||||
m[event] = ""
|
m[event] = ""
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
switch c := command.(type) {
|
switch c := command.(type) {
|
||||||
case JsCommand:
|
case SimpleJsCommand:
|
||||||
eventName := hx.FormatEventName(event, true)
|
eventName := hx.FormatEventName(event, true)
|
||||||
m[eventName] += fmt.Sprintf("%s;", c.Command)
|
m[eventName] += fmt.Sprintf("%s;", c.Command)
|
||||||
|
case ComplexJsCommand:
|
||||||
|
eventName := hx.FormatEventName(event, true)
|
||||||
|
context.AddScript(c.TempFuncName, c.Command)
|
||||||
|
m[eventName] += fmt.Sprintf("%s();", c.TempFuncName)
|
||||||
case *AttributeMap:
|
case *AttributeMap:
|
||||||
for k, v := range c.ToMap() {
|
for k, v := range c.ToMap() {
|
||||||
l.fromAttributeMap(event, k, v, builder)
|
l.fromAttributeMap(event, k, v, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -129,5 +168,5 @@ func (l *LifeCycle) Render(builder *strings.Builder) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Children(children...).Render(builder)
|
Children(children...).Render(context)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
framework/internal/util/random.go
Normal file
13
framework/internal/util/random.go
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
|
|
||||||
|
func RandSeq(n int) string {
|
||||||
|
b := make([]rune, n)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = letters[rand.Intn(len(letters))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,9 @@ COPY go.mod go.sum ./
|
||||||
# Download and cache the Go modules
|
# Download and cache the Go modules
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
|
|
||||||
|
# Always download the latest version of the framework
|
||||||
|
RUN go get github.com/maddalax/htmgo/framework@latest
|
||||||
|
|
||||||
# Copy the source code into the container
|
# Copy the source code into the container
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ go 1.23.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/labstack/echo/v4 v4.12.0
|
github.com/labstack/echo/v4 v4.12.0
|
||||||
github.com/maddalax/htmgo/framework v0.0.0-20240921174901-797c439244a5
|
github.com/maddalax/htmgo/framework v0.0.0-20240921191008-59900b59eaaa
|
||||||
github.com/mattn/go-sqlite3 v1.14.16
|
github.com/mattn/go-sqlite3 v1.14.16
|
||||||
github.com/yuin/goldmark v1.7.4
|
github.com/yuin/goldmark v1.7.4
|
||||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ github.com/maddalax/htmgo/framework v0.0.0-20240921172455-97affb99b5dd h1:zA5itp
|
||||||
github.com/maddalax/htmgo/framework v0.0.0-20240921172455-97affb99b5dd/go.mod h1:WRIlLlHJG/xB+RR84LgNFq3hwYFKXvLfEEG8RzTUH50=
|
github.com/maddalax/htmgo/framework v0.0.0-20240921172455-97affb99b5dd/go.mod h1:WRIlLlHJG/xB+RR84LgNFq3hwYFKXvLfEEG8RzTUH50=
|
||||||
github.com/maddalax/htmgo/framework v0.0.0-20240921174901-797c439244a5 h1:TX+YMeHPi2hVbDKuYmTRzPUSc3RD/w0WHML+MymsYPs=
|
github.com/maddalax/htmgo/framework v0.0.0-20240921174901-797c439244a5 h1:TX+YMeHPi2hVbDKuYmTRzPUSc3RD/w0WHML+MymsYPs=
|
||||||
github.com/maddalax/htmgo/framework v0.0.0-20240921174901-797c439244a5/go.mod h1:WRIlLlHJG/xB+RR84LgNFq3hwYFKXvLfEEG8RzTUH50=
|
github.com/maddalax/htmgo/framework v0.0.0-20240921174901-797c439244a5/go.mod h1:WRIlLlHJG/xB+RR84LgNFq3hwYFKXvLfEEG8RzTUH50=
|
||||||
|
github.com/maddalax/htmgo/framework v0.0.0-20240921191008-59900b59eaaa h1:YKSx3JUpJfwjl9pF0eDd8OyVIlTp24BPvBNHtv/Vmns=
|
||||||
|
github.com/maddalax/htmgo/framework v0.0.0-20240921191008-59900b59eaaa/go.mod h1:WRIlLlHJG/xB+RR84LgNFq3hwYFKXvLfEEG8RzTUH50=
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
"embed"
|
||||||
"fmt"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/maddalax/htmgo/framework/h"
|
"github.com/maddalax/htmgo/framework/h"
|
||||||
"github.com/maddalax/htmgo/framework/htmgo/service"
|
"github.com/maddalax/htmgo/framework/htmgo/service"
|
||||||
|
|
@ -30,8 +29,6 @@ func main() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("test")
|
|
||||||
|
|
||||||
h.Start(h.AppOpts{
|
h.Start(h.AppOpts{
|
||||||
ServiceLocator: locator,
|
ServiceLocator: locator,
|
||||||
LiveReload: true,
|
LiveReload: true,
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,11 @@ package base
|
||||||
import (
|
import (
|
||||||
"github.com/maddalax/htmgo/framework/h"
|
"github.com/maddalax/htmgo/framework/h"
|
||||||
"htmgo-site/partials"
|
"htmgo-site/partials"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Extensions() string {
|
|
||||||
extensions := []string{"path-deps", "response-targets", "mutation-error"}
|
|
||||||
if h.IsDevelopment() {
|
|
||||||
extensions = append(extensions, "livereload")
|
|
||||||
}
|
|
||||||
return strings.Join(extensions, ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func RootPage(children ...h.Ren) *h.Element {
|
func RootPage(children ...h.Ren) *h.Element {
|
||||||
return h.Html(
|
return h.Html(
|
||||||
h.HxExtension(Extensions()),
|
h.HxExtension(h.BaseExtensions()),
|
||||||
h.Head(
|
h.Head(
|
||||||
h.Meta("viewport", "width=device-width, initial-scale=1"),
|
h.Meta("viewport", "width=device-width, initial-scale=1"),
|
||||||
h.Link("/public/main.css", "stylesheet"),
|
h.Link("/public/main.css", "stylesheet"),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue