Merge pull request #699 from trheyi/main
optimize event binding logic in SUI core for just-in-time mode
This commit is contained in:
commit
67ffd4f91c
7 changed files with 185 additions and 70 deletions
|
|
@ -55,7 +55,9 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume
|
||||||
doc.Find("body").SetAttr("s:ns", namespace)
|
doc.Find("body").SetAttr("s:ns", namespace)
|
||||||
|
|
||||||
// Bind the Page events
|
// Bind the Page events
|
||||||
page.BindEvent(ctx, doc.Selection)
|
if !option.JitMode {
|
||||||
|
page.BindEvent(ctx, doc.Selection, "__page", true)
|
||||||
|
}
|
||||||
|
|
||||||
warnings, err := page.buildComponents(doc, ctx, option)
|
warnings, err := page.buildComponents(doc, ctx, option)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -170,6 +172,9 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind the component events
|
||||||
|
page.BindEvent(ctx, doc.Selection, component, false)
|
||||||
|
|
||||||
body := doc.Selection.Find("body")
|
body := doc.Selection.Find("body")
|
||||||
|
|
||||||
if body.Children().Length() == 0 {
|
if body.Children().Length() == 0 {
|
||||||
|
|
@ -553,6 +558,11 @@ func (page *Page) BuildScripts(ctx *BuildContext, option *BuildOption, component
|
||||||
component = ComponentName(page.Route, option.ScriptMinify)
|
component = ComponentName(page.Route, option.ScriptMinify)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arguments := ""
|
||||||
|
if !ispage {
|
||||||
|
arguments = "arguments[0]"
|
||||||
|
}
|
||||||
|
|
||||||
scripts := []ScriptNode{}
|
scripts := []ScriptNode{}
|
||||||
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" {
|
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" {
|
||||||
return scripts, nil
|
return scripts, nil
|
||||||
|
|
@ -566,17 +576,18 @@ func (page *Page) BuildScripts(ctx *BuildContext, option *BuildOption, component
|
||||||
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 != "" {
|
||||||
source, imports, err = page.CompileTS([]byte(page.Codes.TS.Code), option.ScriptMinify)
|
code := fmt.Sprintf("this.store = new __sui_store(%s);\n%s", arguments, page.Codes.TS.Code)
|
||||||
|
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 != "" {
|
||||||
source, imports, err = page.CompileJS([]byte(page.Codes.JS.Code), option.ScriptMinify)
|
code := fmt.Sprintf("this.store = new __sui_store(%s);\n%s", arguments, page.Codes.JS.Code)
|
||||||
|
source, imports, err = page.CompileJS([]byte(code), option.ScriptMinify)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the script
|
// Add the script
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,9 @@ func (page *Page) Compile(ctx *BuildContext, option *BuildOption) (string, []str
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SUI lib
|
||||||
|
head.AppendHtml("\n\n" + `<script name="sui" type="text/javascript">` + suiLibScript + `</script>` + "\n\n")
|
||||||
|
|
||||||
// Page Config
|
// Page Config
|
||||||
page.Config = page.GetConfig()
|
page.Config = page.GetConfig()
|
||||||
|
|
||||||
|
|
@ -111,6 +114,7 @@ func (page *Page) CompileAsComponent(ctx *BuildContext, option *BuildOption) (st
|
||||||
opt := *option
|
opt := *option
|
||||||
opt.IgnoreDocument = true
|
opt.IgnoreDocument = true
|
||||||
opt.WithWrapper = true
|
opt.WithWrapper = true
|
||||||
|
opt.JitMode = true
|
||||||
doc, warnings, err := page.Build(ctx, &opt)
|
doc, warnings, err := page.Build(ctx, &opt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", warnings, err
|
return "", warnings, err
|
||||||
|
|
@ -262,6 +266,9 @@ func (script ScriptNode) ComponentHTML(ns string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
source := fmt.Sprintf(`function %s(){%s};`, script.Component, script.Source)
|
source := fmt.Sprintf(`function %s(){%s};`, script.Component, script.Source)
|
||||||
|
if script.Component == "" {
|
||||||
|
return "<script " + strings.Join(attrs, " ") + ">\n" + script.Source + "\n</script>"
|
||||||
|
}
|
||||||
return "<script " + strings.Join(attrs, " ") + ">\n" + source + "\n</script>"
|
return "<script " + strings.Join(attrs, " ") + ">\n" + source + "\n</script>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,27 +9,48 @@ import (
|
||||||
"golang.org/x/net/html"
|
"golang.org/x/net/html"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var eventMatcher = NewAttrPrefixMatcher(`s:on-`)
|
||||||
|
|
||||||
// BindEvent is a method that binds events to the page.
|
// BindEvent is a method that binds events to the page.
|
||||||
func (page *Page) BindEvent(ctx *BuildContext, sel *goquery.Selection) {
|
func (page *Page) BindEvent(ctx *BuildContext, sel *goquery.Selection, cn string, ispage bool) {
|
||||||
matcher := NewAttrPrefixMatcher(`s:on-`)
|
|
||||||
sel.FindMatcher(matcher).Each(func(i int, s *goquery.Selection) {
|
sel.FindMatcher(eventMatcher).Each(func(i int, s *goquery.Selection) {
|
||||||
page.appendEventScript(ctx, s)
|
if comp, has := s.Attr("is"); has && ctx.isJitComponent(comp) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
script := GetEventScript(ctx.sequence, s, page.namespace, cn, "event", ispage)
|
||||||
|
if script != nil {
|
||||||
|
ctx.scripts = append(ctx.scripts, *script)
|
||||||
|
ctx.sequence++
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) {
|
// BindEvent is a method that binds events to the component in just-in-time mode.
|
||||||
|
func (parser *TemplateParser) BindEvent(sel *goquery.Selection, ns string, cn string) {
|
||||||
|
sel.FindMatcher(eventMatcher).Each(func(i int, s *goquery.Selection) {
|
||||||
|
script := GetEventScript(parser.sequence, s, ns, cn, "event-jit", false)
|
||||||
|
if script != nil {
|
||||||
|
script.Component = ""
|
||||||
|
script.Parent = "body"
|
||||||
|
parser.scripts = append(parser.scripts, *script)
|
||||||
|
parser.sequence++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEventScript the event script
|
||||||
|
func GetEventScript(sequence int, sel *goquery.Selection, ns string, cn string, prefix string, ispage bool) *ScriptNode {
|
||||||
|
|
||||||
if len(sel.Nodes) == 0 {
|
if len(sel.Nodes) == 0 {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Page events
|
// Page events
|
||||||
events := map[string]string{}
|
events := map[string]string{}
|
||||||
dataUnique := map[string]string{}
|
dataUnique := map[string]string{}
|
||||||
jsonUnique := map[string]string{}
|
jsonUnique := map[string]string{}
|
||||||
id := fmt.Sprintf("event-%d", ctx.sequence)
|
id := fmt.Sprintf("%s-%d", prefix, sequence)
|
||||||
ctx.sequence++
|
|
||||||
|
|
||||||
for _, attr := range sel.Nodes[0].Attr {
|
for _, attr := range sel.Nodes[0].Attr {
|
||||||
|
|
||||||
if strings.HasPrefix(attr.Key, "s:on-") {
|
if strings.HasPrefix(attr.Key, "s:on-") {
|
||||||
|
|
@ -71,15 +92,20 @@ func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) {
|
||||||
|
|
||||||
source := ""
|
source := ""
|
||||||
for name, handler := range events {
|
for name, handler := range events {
|
||||||
|
if ispage {
|
||||||
source += pageEventInjectScript(id, name, dataRaw, jsonRaw, handler) + "\n"
|
source += pageEventInjectScript(id, name, dataRaw, jsonRaw, handler) + "\n"
|
||||||
|
} else {
|
||||||
|
source += compEventInjectScript(id, name, cn, dataRaw, jsonRaw, handler) + "\n"
|
||||||
|
}
|
||||||
sel.RemoveAttr(fmt.Sprintf("s:on-%s", name))
|
sel.RemoveAttr(fmt.Sprintf("s:on-%s", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.scripts = append(ctx.scripts, ScriptNode{
|
|
||||||
Source: source,
|
|
||||||
Namespace: page.namespace,
|
|
||||||
Attrs: []html.Attribute{{Key: "event", Val: id}},
|
|
||||||
})
|
|
||||||
|
|
||||||
sel.SetAttr("s:event", id)
|
sel.SetAttr("s:event", id)
|
||||||
|
|
||||||
|
return &ScriptNode{
|
||||||
|
Source: source,
|
||||||
|
Namespace: ns,
|
||||||
|
Component: cn,
|
||||||
|
Attrs: []html.Attribute{{Key: "event", Val: id}},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,7 @@ package core
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
const initScriptTmpl = `
|
const suiLibScript = `
|
||||||
try {
|
|
||||||
var __sui_data = %s;
|
|
||||||
} catch (e) { console.log('init data error:', e); }
|
|
||||||
|
|
||||||
|
|
||||||
function __sui_event_handler(event, dataKeys, jsonKeys, elm, handler) {
|
function __sui_event_handler(event, dataKeys, jsonKeys, elm, handler) {
|
||||||
const data = {};
|
const data = {};
|
||||||
|
|
@ -30,6 +26,43 @@ const initScriptTmpl = `
|
||||||
handler && handler(event, data, elm);
|
handler && handler(event, data, elm);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function __sui_store(elm) {
|
||||||
|
elm = elm || document.body;
|
||||||
|
|
||||||
|
this.Get = function (key) {
|
||||||
|
return elm.getAttribute("data:" + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Set = function (key, value) {
|
||||||
|
elm.setAttribute("data:" + key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.GetJSON = function (key) {
|
||||||
|
const value = elm.getAttribute("json:" + key);
|
||||||
|
if (value && value != "") {
|
||||||
|
try {
|
||||||
|
const res = JSON.parse(value);
|
||||||
|
return res;
|
||||||
|
} catch (e) {
|
||||||
|
const message = e.message || e || "An error occurred";
|
||||||
|
console.error(` + "`[SUI] Event Handler Error: ${message}`" + `, elm);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.SetJSON = function (key, value) {
|
||||||
|
elm.setAttribute("json:" + key, JSON.stringify(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const initScriptTmpl = `
|
||||||
|
try {
|
||||||
|
var __sui_data = %s;
|
||||||
|
} catch (e) { console.log('init data error:', e); }
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
try {
|
try {
|
||||||
document.querySelectorAll("[s\\:ready]").forEach(function (element) {
|
document.querySelectorAll("[s\\:ready]").forEach(function (element) {
|
||||||
|
|
@ -71,6 +104,15 @@ const pageEventScriptTmpl = `
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const compEventScriptTmpl = `
|
||||||
|
document.querySelector("[s\\:event=%s]").addEventListener("%s", function (event) {
|
||||||
|
const dataKeys = %s;
|
||||||
|
const jsonKeys = %s;
|
||||||
|
const handler = new %s(this).%s;
|
||||||
|
__sui_event_handler(event, dataKeys, jsonKeys, this, handler);
|
||||||
|
});
|
||||||
|
`
|
||||||
|
|
||||||
func bodyInjectionScript(jsonRaw string, debug bool) string {
|
func bodyInjectionScript(jsonRaw string, debug bool) string {
|
||||||
jsPrintData := ""
|
jsPrintData := ""
|
||||||
if debug {
|
if debug {
|
||||||
|
|
@ -86,3 +128,7 @@ func headInjectionScript(jsonRaw string) string {
|
||||||
func pageEventInjectScript(eventID, eventName, dataKeys, jsonKeys, handler string) string {
|
func pageEventInjectScript(eventID, eventName, dataKeys, jsonKeys, handler string) string {
|
||||||
return fmt.Sprintf(pageEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, handler)
|
return fmt.Sprintf(pageEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func compEventInjectScript(eventID, eventName, component, dataKeys, jsonKeys, handler string) string {
|
||||||
|
return fmt.Sprintf(compEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, component, handler)
|
||||||
|
}
|
||||||
|
|
|
||||||
105
sui/core/jit.go
105
sui/core/jit.go
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/PuerkitoBio/goquery"
|
"github.com/PuerkitoBio/goquery"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
|
|
@ -62,21 +61,24 @@ func (parser *TemplateParser) parseComponent(sel *goquery.Selection) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fmt.Println(sel.Nodes[0].Attr)
|
||||||
sel.SetHtml(html)
|
sel.SetHtml(html)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RenderComponent render the component
|
// RenderComponent render the component
|
||||||
func (parser *TemplateParser) RenderComponent(comp *JitComponent, props map[string]interface{}, slots *goquery.Selection, children *goquery.Selection) (string, string, error) {
|
func (parser *TemplateParser) RenderComponent(comp *JitComponent, props map[string]interface{}, slots *goquery.Selection, children *goquery.Selection) (string, string, error) {
|
||||||
html := comp.html
|
html := comp.html
|
||||||
randvar := fmt.Sprintf("__%s_$props", time.Now().Format("20060102150405"))
|
|
||||||
html = replaceRandVar(html, randvar)
|
html = replaceRandVar(html, Data(props))
|
||||||
data := Data{}
|
option := *parser.option
|
||||||
data[randvar] = props
|
option.Route = comp.route
|
||||||
if parser.data != nil {
|
compParser := NewTemplateParser(parser.data, &option)
|
||||||
for key, val := range parser.data {
|
compParser.sequence = parser.sequence + 1
|
||||||
data[key] = val
|
locale := compParser.Locale()
|
||||||
}
|
|
||||||
}
|
// Parse the node
|
||||||
|
ns := Namespace(comp.route, compParser.sequence, comp.buildOption.ScriptMinify)
|
||||||
|
cn := ComponentName(comp.route, comp.buildOption.ScriptMinify)
|
||||||
|
|
||||||
sel, err := NewDocumentString(`<body>` + html + `</body>`)
|
sel, err := NewDocumentString(`<body>` + html + `</body>`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -106,24 +108,26 @@ func (parser *TemplateParser) RenderComponent(comp *JitComponent, props map[stri
|
||||||
children.Find("slot").Remove()
|
children.Find("slot").Remove()
|
||||||
root.Find("children").ReplaceWithSelection(children)
|
root.Find("children").ReplaceWithSelection(children)
|
||||||
|
|
||||||
option := *parser.option
|
// Replace the props
|
||||||
option.Route = comp.route
|
|
||||||
compParser := NewTemplateParser(data, &option)
|
|
||||||
locale := compParser.Locale()
|
|
||||||
if locale != nil {
|
if locale != nil {
|
||||||
locale.replaceVars(randvar)
|
locale.replaceVars(Data(props))
|
||||||
}
|
}
|
||||||
compParser.locale = locale
|
|
||||||
|
|
||||||
// Parse the node
|
compParser.locale = locale
|
||||||
ns := Namespace(comp.route, compParser.sequence, comp.buildOption.ScriptMinify)
|
compParser.BindEvent(root, ns, cn)
|
||||||
cn := ComponentName(comp.route, comp.buildOption.ScriptMinify)
|
|
||||||
compParser.parseNode(root.Get(0))
|
compParser.parseNode(root.Get(0))
|
||||||
for sel, nodes := range compParser.replace {
|
for sel, nodes := range compParser.replace {
|
||||||
sel.ReplaceWithNodes(nodes...)
|
sel.ReplaceWithNodes(nodes...)
|
||||||
delete(parser.replace, sel)
|
delete(parser.replace, sel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if compParser.scripts != nil {
|
||||||
|
for _, script := range compParser.scripts {
|
||||||
|
script.Namespace = ns
|
||||||
|
parser.scripts = append(parser.scripts, script)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if comp.scripts != nil {
|
if comp.scripts != nil {
|
||||||
for _, script := range comp.scripts {
|
for _, script := range comp.scripts {
|
||||||
script.Namespace = ns
|
script.Namespace = ns
|
||||||
|
|
@ -144,6 +148,7 @@ func (parser *TemplateParser) RenderComponent(comp *JitComponent, props map[stri
|
||||||
first.SetAttr("s:ns", ns)
|
first.SetAttr("s:ns", ns)
|
||||||
first.SetAttr("s:cn", cn)
|
first.SetAttr("s:cn", cn)
|
||||||
first.SetAttr("s:ready", cn+"()")
|
first.SetAttr("s:ready", cn+"()")
|
||||||
|
|
||||||
html, err = root.Html()
|
html, err = root.Html()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
|
|
@ -151,15 +156,28 @@ func (parser *TemplateParser) RenderComponent(comp *JitComponent, props map[stri
|
||||||
return html, ns, nil
|
return html, ns, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parser *TemplateParser) addScripts(sel *goquery.Selection, scripts []ScriptNode) {
|
func (parser *TemplateParser) filterScripts(parent string, scripts []ScriptNode) []ScriptNode {
|
||||||
if scripts == nil {
|
if scripts == nil {
|
||||||
return
|
return []ScriptNode{}
|
||||||
}
|
}
|
||||||
|
filtered := []ScriptNode{}
|
||||||
for _, script := range scripts {
|
for _, script := range scripts {
|
||||||
|
if script.Parent != parent {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filtered = append(filtered, script)
|
||||||
|
}
|
||||||
|
return filtered
|
||||||
|
}
|
||||||
|
|
||||||
|
func (parser *TemplateParser) addScripts(sel *goquery.Selection, scripts []ScriptNode) {
|
||||||
|
for _, script := range scripts {
|
||||||
|
if script.Component != "" {
|
||||||
query := fmt.Sprintf(`script[s\:cn="%s"]`, script.Component)
|
query := fmt.Sprintf(`script[s\:cn="%s"]`, script.Component)
|
||||||
if sel.Find(query).Length() > 0 {
|
if sel.Find(query).Length() > 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sel.AppendHtml(script.ComponentHTML(script.Namespace))
|
sel.AppendHtml(script.ComponentHTML(script.Namespace))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,6 +244,13 @@ func (parser *TemplateParser) componentProps(sel *goquery.Selection) (map[string
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, attr := range sel.Nodes[0].Attr {
|
for _, attr := range sel.Nodes[0].Attr {
|
||||||
|
|
||||||
|
// s:on , s:data , s:json
|
||||||
|
if strings.HasPrefix(attr.Key, "s:on") || strings.HasPrefix(attr.Key, "s:data") || strings.HasPrefix(attr.Key, "s:json") {
|
||||||
|
props[attr.Key] = attr.Val
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(attr.Key, "s:") || attr.Key == "is" {
|
if strings.HasPrefix(attr.Key, "s:") || attr.Key == "is" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
@ -268,22 +293,13 @@ func (parser *TemplateParser) parseComponentProps(props map[string]string) (map[
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := values.(map[string]interface{}); ok {
|
if _, ok := values.(map[string]interface{}); ok {
|
||||||
for k, v := range values.(map[string]interface{}) {
|
for k := range values.(map[string]interface{}) {
|
||||||
result[k] = v
|
result[k] = k
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
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] = val
|
result[key] = val
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
@ -303,16 +319,16 @@ func (parser *TemplateParser) componentFile(sel *goquery.Selection, props map[st
|
||||||
return file, route, nil
|
return file, route, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (locale *Locale) replaceVars(randvar string) {
|
func (locale *Locale) replaceVars(data Data) {
|
||||||
if locale.Keys != nil {
|
if locale.Keys != nil {
|
||||||
for key, val := range locale.Keys {
|
for key, val := range locale.Keys {
|
||||||
locale.Keys[key] = replaceRandVar(val, randvar)
|
locale.Keys[key] = replaceRandVar(val, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if locale.Messages != nil {
|
if locale.Messages != nil {
|
||||||
for key, val := range locale.Messages {
|
for key, val := range locale.Messages {
|
||||||
locale.Messages[key] = replaceRandVar(val, randvar)
|
locale.Messages[key] = replaceRandVar(val, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -414,11 +430,18 @@ func readComponent(route string, file string) (*JitComponent, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func replaceRandVar(html string, randvar string) string {
|
func replaceRandVar(value string, data Data) string {
|
||||||
return slotRe.ReplaceAllStringFunc(html, func(exp string) string {
|
|
||||||
exp = strings.ReplaceAll(exp, "[{", "{{")
|
value = propNewRe.ReplaceAllStringFunc(value, func(exp string) string {
|
||||||
exp = strings.ReplaceAll(exp, "}]", "}}")
|
exp = strings.TrimPrefix(exp, "{%")
|
||||||
exp = strings.ReplaceAll(exp, "$props", randvar)
|
exp = strings.TrimSuffix(exp, "%}")
|
||||||
return exp
|
res, _ := data.ExecString(fmt.Sprintf("{{ %s }}", exp))
|
||||||
|
return res
|
||||||
|
})
|
||||||
|
|
||||||
|
data = Data{"$props": data}
|
||||||
|
return slotRe.ReplaceAllStringFunc(value, func(exp string) string {
|
||||||
|
res, _ := data.ExecString(exp)
|
||||||
|
return res
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ func (parser *TemplateParser) Render(html string) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
head.AppendHtml(headInjectionScript(data))
|
head.AppendHtml(headInjectionScript(data))
|
||||||
parser.addScripts(head, parser.scripts)
|
parser.addScripts(head, parser.filterScripts("head", parser.scripts))
|
||||||
parser.addStyles(head, parser.styles)
|
parser.addStyles(head, parser.styles)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,6 +146,7 @@ func (parser *TemplateParser) Render(html string) (string, error) {
|
||||||
data, _ = jsoniter.MarshalToString(map[string]string{"error": err.Error()})
|
data, _ = jsoniter.MarshalToString(map[string]string{"error": err.Error()})
|
||||||
}
|
}
|
||||||
body.AppendHtml(bodyInjectionScript(data, parser.debug()))
|
body.AppendHtml(bodyInjectionScript(data, parser.debug()))
|
||||||
|
parser.addScripts(body, parser.filterScripts("body", parser.scripts))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fmt
|
// Fmt
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,7 @@ type BuildOption struct {
|
||||||
AssetRoot string `json:"asset_root,omitempty"`
|
AssetRoot string `json:"asset_root,omitempty"`
|
||||||
IgnoreAssetRoot bool `json:"ignore_asset_root,omitempty"`
|
IgnoreAssetRoot bool `json:"ignore_asset_root,omitempty"`
|
||||||
IgnoreDocument bool `json:"ignore_document,omitempty"`
|
IgnoreDocument bool `json:"ignore_document,omitempty"`
|
||||||
|
JitMode bool `json:"jit_mode,omitempty"`
|
||||||
WithWrapper bool `json:"with_wrapper,omitempty"`
|
WithWrapper bool `json:"with_wrapper,omitempty"`
|
||||||
KeepPageTag bool `json:"keep_page_tag,omitempty"`
|
KeepPageTag bool `json:"keep_page_tag,omitempty"`
|
||||||
Namespace string `json:"namespace,omitempty"`
|
Namespace string `json:"namespace,omitempty"`
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue