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
|
||||
}
|
||||
|
||||
// Bind the component events
|
||||
page.BindEvent(ctx, doc.Selection, component)
|
||||
|
||||
body := doc.Selection.Find("body")
|
||||
|
||||
if body.Children().Length() == 0 {
|
||||
|
|
@ -553,6 +556,11 @@ func (page *Page) BuildScripts(ctx *BuildContext, option *BuildOption, component
|
|||
component = ComponentName(page.Route, option.ScriptMinify)
|
||||
}
|
||||
|
||||
arguments := ""
|
||||
if !ispage {
|
||||
arguments = "arguments[0]"
|
||||
}
|
||||
|
||||
scripts := []ScriptNode{}
|
||||
if page.Codes.JS.Code == "" && page.Codes.TS.Code == "" {
|
||||
return scripts, nil
|
||||
|
|
@ -566,17 +574,18 @@ func (page *Page) BuildScripts(ctx *BuildContext, option *BuildOption, component
|
|||
var imports []string = nil
|
||||
var source []byte = nil
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
} 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 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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.GetConfig()
|
||||
|
||||
|
|
|
|||
|
|
@ -10,14 +10,26 @@ import (
|
|||
)
|
||||
|
||||
// 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-`)
|
||||
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 {
|
||||
return
|
||||
|
|
@ -71,13 +83,18 @@ func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) {
|
|||
|
||||
source := ""
|
||||
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))
|
||||
}
|
||||
|
||||
ctx.scripts = append(ctx.scripts, ScriptNode{
|
||||
Source: source,
|
||||
Namespace: page.namespace,
|
||||
Component: component,
|
||||
Attrs: []html.Attribute{{Key: "event", Val: id}},
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,7 @@ package core
|
|||
|
||||
import "fmt"
|
||||
|
||||
const initScriptTmpl = `
|
||||
try {
|
||||
var __sui_data = %s;
|
||||
} catch (e) { console.log('init data error:', e); }
|
||||
|
||||
const suiLibScript = `
|
||||
|
||||
function __sui_event_handler(event, dataKeys, jsonKeys, elm, handler) {
|
||||
const data = {};
|
||||
|
|
@ -26,10 +22,47 @@ const initScriptTmpl = `
|
|||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
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 () {
|
||||
try {
|
||||
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 {
|
||||
jsPrintData := ""
|
||||
if debug {
|
||||
|
|
@ -86,3 +128,7 @@ func headInjectionScript(jsonRaw string) string {
|
|||
func pageEventInjectScript(eventID, eventName, dataKeys, jsonKeys, handler string) string {
|
||||
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