Refactor event binding logic in SUI core
This commit is contained in:
parent
bafe3bb20f
commit
fbfd3f270a
4 changed files with 88 additions and 13 deletions
|
|
@ -170,6 +170,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)
|
||||||
|
|
||||||
body := doc.Selection.Find("body")
|
body := doc.Selection.Find("body")
|
||||||
|
|
||||||
if body.Children().Length() == 0 {
|
if body.Children().Length() == 0 {
|
||||||
|
|
@ -553,6 +556,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 +574,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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,26 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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, component ...string) {
|
||||||
|
|
||||||
|
// Component events
|
||||||
|
if len(component) > 0 && component[0] != "" {
|
||||||
|
fmt.Println("component events:", page.Route, component[0])
|
||||||
|
matcher := NewAttrPrefixMatcher(`s:on-`)
|
||||||
|
sel.FindMatcher(matcher).Each(func(i int, s *goquery.Selection) {
|
||||||
|
fmt.Println("\tcomponent event", i, s.Nodes[0].Data)
|
||||||
|
page.appendEventScript(ctx, s, component[0])
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
matcher := NewAttrPrefixMatcher(`s:on-`)
|
matcher := NewAttrPrefixMatcher(`s:on-`)
|
||||||
sel.FindMatcher(matcher).Each(func(i int, s *goquery.Selection) {
|
sel.FindMatcher(matcher).Each(func(i int, s *goquery.Selection) {
|
||||||
page.appendEventScript(ctx, s)
|
page.appendEventScript(ctx, s, "")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) {
|
func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection, component string) {
|
||||||
|
|
||||||
if len(sel.Nodes) == 0 {
|
if len(sel.Nodes) == 0 {
|
||||||
return
|
return
|
||||||
|
|
@ -71,13 +83,18 @@ func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) {
|
||||||
|
|
||||||
source := ""
|
source := ""
|
||||||
for name, handler := range events {
|
for name, handler := range events {
|
||||||
source += pageEventInjectScript(id, name, dataRaw, jsonRaw, handler) + "\n"
|
if component == "" {
|
||||||
|
source += pageEventInjectScript(id, name, dataRaw, jsonRaw, handler) + "\n"
|
||||||
|
} else {
|
||||||
|
source += compEventInjectScript(id, name, component, 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{
|
ctx.scripts = append(ctx.scripts, ScriptNode{
|
||||||
Source: source,
|
Source: source,
|
||||||
Namespace: page.namespace,
|
Namespace: page.namespace,
|
||||||
|
Component: component,
|
||||||
Attrs: []html.Attribute{{Key: "event", Val: id}},
|
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 = {};
|
||||||
|
|
@ -26,10 +22,47 @@ 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)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue