Refactor component initialization in SUI core

This commit is contained in:
Max 2024-07-22 20:37:51 +08:00
parent 2f828b643d
commit 9101efb4b6
4 changed files with 91 additions and 6 deletions

View file

@ -583,10 +583,11 @@ func (page *Page) BuildScripts(ctx *BuildContext, option *BuildOption, component
component = ComponentName(page.Route, option.ScriptMinify) component = ComponentName(page.Route, option.ScriptMinify)
} }
arguments := "" arguments := "document.body"
if !ispage { if !ispage {
arguments = "arguments[0]" arguments = "arguments[0]"
} }
injectScript := componentInitScript(arguments)
scripts := []ScriptNode{} scripts := []ScriptNode{}
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" { 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 ctx.scriptUnique[component] = true
var err error = nil var err error = nil
var imports []string = nil var imports []string = nil
var source []byte = nil var source []byte = nil
if page.Codes.TS.Code != "" { 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) source, imports, err = page.CompileTS([]byte(code), option.ScriptMinify)
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else if page.Codes.JS.Code != "" { } 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) source, imports, err = page.CompileJS([]byte(code), option.ScriptMinify)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -25,6 +25,8 @@ type Data map[string]interface{}
var options = []expr.Option{ var options = []expr.Option{
expr.Function("P_", _process), expr.Function("P_", _process),
expr.Function("True", _true),
expr.Function("False", _false),
expr.AllowUndefinedVariables(), 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) { func _process(args ...any) (interface{}, error) {
if len(args) < 1 { if len(args) < 1 {

View file

@ -1,9 +1,35 @@
package core package core
import "fmt" import (
"fmt"
)
const suiLibScript = ` 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) { function __sui_event_handler(event, dataKeys, jsonKeys, elm, handler) {
const data = {}; const data = {};
dataKeys.forEach(function (key) { 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) { function __sui_store(elm) {
@ -108,11 +139,16 @@ const compEventScriptTmpl = `
document.querySelector("[s\\:event=%s]").addEventListener("%s", function (event) { document.querySelector("[s\\:event=%s]").addEventListener("%s", function (event) {
const dataKeys = %s; const dataKeys = %s;
const jsonKeys = %s; const jsonKeys = %s;
const handler = new %s(this).%s; component = new %s(this).%s;
__sui_event_handler(event, dataKeys, jsonKeys, this, handler); __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 { func bodyInjectionScript(jsonRaw string, debug bool) string {
jsPrintData := "" jsPrintData := ""
if debug { if debug {
@ -132,3 +168,7 @@ func pageEventInjectScript(eventID, eventName, dataKeys, jsonKeys, handler strin
func compEventInjectScript(eventID, eventName, component, dataKeys, jsonKeys, handler string) string { func compEventInjectScript(eventID, eventName, component, dataKeys, jsonKeys, handler string) string {
return fmt.Sprintf(compEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, component, handler) return fmt.Sprintf(compEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, component, handler)
} }
func componentInitScript(root string) string {
return fmt.Sprintf(componentInitScriptTmpl, root)
}

View file

@ -420,6 +420,17 @@ func (parser *TemplateParser) parseElementAttrs(sel *goquery.Selection) {
attrs := sel.Nodes[0].Attr attrs := sel.Nodes[0].Attr
for _, attr := range attrs { 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 // Ignore the s: attributes
if strings.HasPrefix(attr.Key, "s:") { if strings.HasPrefix(attr.Key, "s:") {
continue continue