From a3d2baef40bbcce97c59bc4ff4f2e987c281be14 Mon Sep 17 00:00:00 2001 From: Max Date: Fri, 30 Aug 2024 10:42:25 +0800 Subject: [PATCH] Refactor component attribute handling to support spread operator --- sui/core/jit.go | 40 +++++++++++++++++++++++++++++++++++----- sui/core/parser.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/sui/core/jit.go b/sui/core/jit.go index f782de5c75..51311a6ce3 100644 --- a/sui/core/jit.go +++ b/sui/core/jit.go @@ -76,12 +76,47 @@ func (parser *TemplateParser) newJitComponentSel(sel *goquery.Selection, comp *J "s:cn": cn, "s:ready": cn + "()", } + + doc, err := NewDocumentString(comp.html) + if err != nil { + return nil, fmt.Errorf("Component %s failed to load, please recompile the component. %s", comp.route, err.Error()) + } + compSel := doc.Find("body").Children().First() data := Data{} for _, attr := range sel.Nodes[0].Attr { if attr.Key == "is" || attr.Key == "s:jit" { continue } + // ...variable + if strings.HasPrefix(attr.Key, "...") { + key := attr.Key[3:] + if parser.data != nil { + if values, ok := parser.data[key].(map[string]any); ok { + for name, value := range values { + switch v := value.(type) { + case string: + props[name] = v + case bool, int, float64: + props[name] = fmt.Sprintf("%v", v) + + case nil: + props[name] = "" + + default: + str, err := jsoniter.MarshalToString(value) + if err != nil { + continue + } + props[name] = str + props[fmt.Sprintf("json-attr-%s", name)] = "true" + } + } + } + } + continue + } + val, values := parser.data.Replace(attr.Val) if HasJSON(values) { props[fmt.Sprintf("json-attr-%s", attr.Key)] = "true" @@ -90,11 +125,6 @@ func (parser *TemplateParser) newJitComponentSel(sel *goquery.Selection, comp *J data[attr.Key] = val } - doc, err := NewDocumentString(comp.html) - if err != nil { - return nil, fmt.Errorf("Component %s failed to load, please recompile the component. %s", comp.route, err.Error()) - } - compSel := doc.Find("body").Children().First() data.replaceNodeUse(propTokens, compSel.Nodes[0]) for key, val := range props { if strings.HasPrefix(key, "s:") || key == "parsed" { diff --git a/sui/core/parser.go b/sui/core/parser.go index 9234dd67dd..512590db1d 100644 --- a/sui/core/parser.go +++ b/sui/core/parser.go @@ -559,6 +559,35 @@ func (parser *TemplateParser) parseElementAttrs(sel *goquery.Selection, force .. continue } + // ...variable + if strings.HasPrefix(attr.Key, "...") { + key := attr.Key[3:] + if parser.data != nil { + if values, ok := parser.data[key].(map[string]any); ok { + for name, value := range values { + switch v := value.(type) { + case string: + sel.SetAttr(name, v) + case bool, int, float64: + sel.SetAttr(name, fmt.Sprintf("%v", v)) + + case nil: + sel.SetAttr(name, "") + + default: + str, err := jsoniter.MarshalToString(value) + if err != nil { + continue + } + sel.SetAttr(name, str) + sel.SetAttr(fmt.Sprintf("json-attr-%s", name), "true") + } + } + } + continue + } + } + parser.sequence = parser.sequence + 1 res, values := parser.data.Replace(attr.Val) if values != nil && len(values) > 0 {