diff --git a/sui/core/build.go b/sui/core/build.go index 1c752e00..c521713c 100644 --- a/sui/core/build.go +++ b/sui/core/build.go @@ -583,10 +583,11 @@ func (page *Page) BuildScripts(ctx *BuildContext, option *BuildOption, component component = ComponentName(page.Route, option.ScriptMinify) } - arguments := "" + arguments := "document.body" if !ispage { arguments = "arguments[0]" } + injectScript := componentInitScript(arguments) scripts := []ScriptNode{} if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" { @@ -597,18 +598,19 @@ func (page *Page) BuildScripts(ctx *BuildContext, option *BuildOption, component } ctx.scriptUnique[component] = true + var err error = nil var imports []string = nil var source []byte = nil if page.Codes.TS.Code != "" { - code := fmt.Sprintf("this.store = new __sui_store(%s);\n%s", arguments, page.Codes.TS.Code) + code := fmt.Sprintf("%s\n%s", injectScript, page.Codes.TS.Code) source, imports, err = page.CompileTS([]byte(code), option.ScriptMinify) if err != nil { return nil, err } } else if page.Codes.JS.Code != "" { - code := fmt.Sprintf("this.store = new __sui_store(%s);\n%s", arguments, page.Codes.JS.Code) + code := fmt.Sprintf("%s\n%s", injectScript, page.Codes.JS.Code) source, imports, err = page.CompileJS([]byte(code), option.ScriptMinify) if err != nil { return nil, err diff --git a/sui/core/data.go b/sui/core/data.go index 9fc26e95..cfcbd216 100644 --- a/sui/core/data.go +++ b/sui/core/data.go @@ -25,6 +25,8 @@ type Data map[string]interface{} var options = []expr.Option{ expr.Function("P_", _process), + expr.Function("True", _true), + expr.Function("False", _false), expr.AllowUndefinedVariables(), } @@ -162,6 +164,36 @@ func (data Data) replaceNodeUse(re *regexp.Regexp, node *html.Node) bool { } +func _false(args ...any) (interface{}, error) { + v, err := _true(args...) + if err != nil { + return false, err + } + return !v.(bool), nil +} + +func _true(args ...any) (interface{}, error) { + + if len(args) < 1 { + return false, nil + } + + if v, ok := args[0].(bool); ok { + return v, nil + } + + if v, ok := args[0].(string); ok { + v = strings.ToLower(v) + return v != "false" && v != "0", nil + } + + if v, ok := args[0].(int); ok { + return v != 0, nil + } + + return false, nil +} + func _process(args ...any) (interface{}, error) { if len(args) < 1 { diff --git a/sui/core/injections.go b/sui/core/injections.go index 70375ad8..3a7ab0ce 100644 --- a/sui/core/injections.go +++ b/sui/core/injections.go @@ -1,9 +1,35 @@ package core -import "fmt" +import ( + "fmt" +) const suiLibScript = ` + function __sui_state(component) { + this.handlers = component.watch || {}; + this.Set = async function (key, value) { + const handler = this.handlers[key]; + if (handler && typeof handler === "function") { + await handler(value); + } + } + } + + function __sui_props(elm) { + this.Get = function (key) { + return elm && elm.getAttribute(key); + } + } + + function __sui_component(elm, component) { + console.log('elm', component); + this.root = elm; + this.store = new __sui_store(elm); + this.props = new __sui_props(elm); + this.state = component ? new __sui_state(component) : {}; + } + function __sui_event_handler(event, dataKeys, jsonKeys, elm, handler) { const data = {}; dataKeys.forEach(function (key) { @@ -23,7 +49,12 @@ const suiLibScript = ` } }) - handler && handler(event, data, elm); + const cn = elm.getAttribute("s:cn"); + let component = null + if (cn != "") { + component = new window[cn](elm); + } + handler && handler(event, data, new __sui_component(elm, component)); }; function __sui_store(elm) { @@ -108,11 +139,16 @@ const compEventScriptTmpl = ` document.querySelector("[s\\:event=%s]").addEventListener("%s", function (event) { const dataKeys = %s; const jsonKeys = %s; - const handler = new %s(this).%s; + component = new %s(this).%s; __sui_event_handler(event, dataKeys, jsonKeys, this, handler); }); ` +const componentInitScriptTmpl = ` + this.root = %s; + this.store = new __sui_store(this.root); +` + func bodyInjectionScript(jsonRaw string, debug bool) string { jsPrintData := "" if debug { @@ -132,3 +168,7 @@ func pageEventInjectScript(eventID, eventName, dataKeys, jsonKeys, handler strin func compEventInjectScript(eventID, eventName, component, dataKeys, jsonKeys, handler string) string { return fmt.Sprintf(compEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, component, handler) } + +func componentInitScript(root string) string { + return fmt.Sprintf(componentInitScriptTmpl, root) +} diff --git a/sui/core/parser.go b/sui/core/parser.go index a3db3bed..3b6be196 100644 --- a/sui/core/parser.go +++ b/sui/core/parser.go @@ -420,6 +420,17 @@ func (parser *TemplateParser) parseElementAttrs(sel *goquery.Selection) { attrs := sel.Nodes[0].Attr for _, attr := range attrs { + if strings.HasPrefix(attr.Key, "s:attr-") { + parser.sequence = parser.sequence + 1 + val, _ := parser.data.Exec(attr.Val) + if v, ok := val.(bool); ok { + if v { + sel.SetAttr(strings.TrimPrefix(attr.Key, "s:attr-"), "") + } + } + continue + } + // Ignore the s: attributes if strings.HasPrefix(attr.Key, "s:") { continue