diff --git a/sui/core/build.go b/sui/core/build.go index 433c0c043..5fc84288f 100644 --- a/sui/core/build.go +++ b/sui/core/build.go @@ -39,6 +39,10 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume } ctx.sequence++ + + namespace := Namespace(page.Name, ctx.sequence, option.ScriptMinify) + page.namespace = namespace + html, err := page.BuildHTML(option) if err != nil { ctx.warnings = append(ctx.warnings, err.Error()) @@ -48,6 +52,7 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume if err != nil { return nil, ctx.warnings, err } + doc.Find("body").SetAttr("s:ns", namespace) err = page.buildComponents(doc, ctx, option) if err != nil { @@ -55,7 +60,6 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume } // Scripts - namespace := Namespace(page.Name, ctx.sequence, option.ScriptMinify) scripts, err := page.BuildScripts(ctx, option, "__page", namespace) if err != nil { return nil, ctx.warnings, err @@ -101,10 +105,12 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op namespace := Namespace(name, ctx.sequence, option.ScriptMinify) component := ComponentName(name, option.ScriptMinify) + page.namespace = namespace attrs := []html.Attribute{ {Key: "s:ns", Val: namespace}, {Key: "s:cn", Val: component}, {Key: "s:ready", Val: component + "()"}, + {Key: "s:parent", Val: page.parent.namespace}, } ctx.sequence++ @@ -264,6 +270,7 @@ func (page *Page) buildComponents(doc *goquery.Document, ctx *BuildContext, opti // Check if Just-In-Time Component ( "is" has variable ) if ctx.isJitComponent(name) { sel.SetAttr("s:jit", "true") + sel.SetAttr("s:parent", page.namespace) sel.SetAttr("s:root", public.Root) ctx.addJitComponent(name) return diff --git a/sui/core/jit.go b/sui/core/jit.go index e9774f80b..6ad82d5fe 100644 --- a/sui/core/jit.go +++ b/sui/core/jit.go @@ -143,18 +143,47 @@ func (parser *TemplateParser) isComponent(sel *goquery.Selection) bool { } func (parser *TemplateParser) componentProps(sel *goquery.Selection) (map[string]interface{}, error) { + + parentProps := map[string]string{} props := map[string]string{} - parentSel := sel.Parent() - if parentSel == nil { - return map[string]interface{}{}, nil + parent := sel.AttrOr("s:parent", "") + parentSel := sel.Parents().Find(fmt.Sprintf(`[s\:ns="%s"]`, parent)) + + if parentSel != nil && parentSel.Length() > 0 { + for _, attr := range parentSel.Nodes[0].Attr { + + if !strings.HasPrefix(attr.Key, "s:prop") { + continue + } + key := strings.TrimPrefix(attr.Key, "s:prop:") + parentProps[key] = attr.Val + } } - for _, attr := range parentSel.Nodes[0].Attr { - if !strings.HasPrefix(attr.Key, "s:prop") { + for _, attr := range sel.Nodes[0].Attr { + if strings.HasPrefix(attr.Key, "s:") || attr.Key == "is" { continue } - key := strings.TrimPrefix(attr.Key, "s:prop:") - props[key] = attr.Val + + if strings.HasPrefix(attr.Key, "...$props") { + data := Data{"$props": parentProps} + values, err := data.Exec(fmt.Sprintf("{{ %s }}", strings.TrimPrefix(attr.Key, "..."))) + if err != nil { + return map[string]interface{}{}, err + } + if values == nil { + continue + } + + if _, ok := values.(map[string]string); ok { + for key, val := range values.(map[string]string) { + props[key] = val + } + } + continue + } + + props[attr.Key] = attr.Val } return parser.parseComponentProps(props) @@ -164,7 +193,7 @@ func (parser *TemplateParser) parseComponentProps(props map[string]string) (map[ result := map[string]interface{}{} for key, val := range props { if strings.HasPrefix(key, "...") { - values, err := parser.data.Exec(fmt.Sprintf("{{ %s }}", val)) + values, err := parser.data.Exec(fmt.Sprintf("{{ %s }}", strings.TrimPrefix(key, "..."))) if err != nil { return nil, err } @@ -173,17 +202,24 @@ func (parser *TemplateParser) parseComponentProps(props map[string]string) (map[ continue } - for k, v := range values.(map[string]interface{}) { - result[k] = v + if _, ok := values.(map[string]interface{}); ok { + for k, v := range values.(map[string]interface{}) { + result[k] = v + } } - continue } - value, err := parser.data.Exec(val) - if err != nil { - return nil, err + + if strings.HasPrefix(val, "{{") && strings.HasSuffix(val, "}}") { + value, err := parser.data.Exec(val) + if err != nil { + return map[string]interface{}{}, err + } + result[key] = value + continue } - result[key] = value + + result[key] = val } return result, nil } diff --git a/sui/core/types.go b/sui/core/types.go index 6eaee9a10..cf2e5d14d 100644 --- a/sui/core/types.go +++ b/sui/core/types.go @@ -42,6 +42,7 @@ type Page struct { Attrs map[string]string `json:"-"` Attributes []html.Attribute `json:"-"` Translations []Translation `json:"-"` // will be deprecated + namespace string `json:"-"` parent *Page `json:"-"` }