Refactor event binding logic in SUI core

This commit is contained in:
Max 2024-07-20 09:44:58 +08:00
parent ebc399bfe1
commit bafe3bb20f
4 changed files with 46 additions and 31 deletions

View file

@ -54,6 +54,9 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume
}
doc.Find("body").SetAttr("s:ns", namespace)
// Bind the Page events
page.BindEvent(ctx, doc.Selection)
warnings, err := page.buildComponents(doc, ctx, option)
if err != nil {
return nil, ctx.warnings, err
@ -106,9 +109,6 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume
ctx.scripts = append(ctx.scripts, scripts...)
ctx.styles = append(ctx.styles, styles...)
// Bind the events
page.BindEvent(ctx, doc.Selection)
return doc, ctx.warnings, err
}
@ -282,6 +282,12 @@ func (page *Page) parseProps(from *goquery.Selection, to *goquery.Selection, ext
for _, attr := range attrs {
// Copy Event
if strings.HasPrefix(attr.Key, "s:event") || strings.HasPrefix(attr.Key, "data:") || strings.HasPrefix(attr.Key, "json:") {
to.SetAttr(attr.Key, attr.Val)
continue
}
if strings.HasPrefix(attr.Key, "s:") || attr.Key == "is" || attr.Key == "parsed" {
continue
}

View file

@ -18,9 +18,6 @@ func (page *Page) BindEvent(ctx *BuildContext, sel *goquery.Selection) {
}
func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) {
if page.parent != nil {
return
}
if len(sel.Nodes) == 0 {
return
@ -34,34 +31,39 @@ func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) {
ctx.sequence++
for _, attr := range sel.Nodes[0].Attr {
if strings.HasPrefix(attr.Key, "s:on-") {
name := strings.TrimPrefix(attr.Key, "s:on-")
handler := attr.Val
events[name] = handler
continue
}
if strings.HasPrefix(attr.Key, "s:data-") {
name := strings.TrimPrefix(attr.Key, "s:data-")
dataUnique[name] = attr.Val
sel.RemoveAttr(attr.Key)
sel.RemoveAttr(attr.Key)
sel.SetAttr(fmt.Sprintf("data:%s", name), attr.Val)
continue
}
if strings.HasPrefix(attr.Key, "s:json-") {
name := strings.TrimPrefix(attr.Key, "s:json-")
jsonUnique[name] = attr.Val
sel.RemoveAttr(attr.Key)
sel.SetAttr(fmt.Sprintf("json:%s", name), attr.Val)
continue
}
}
data := []string{}
for name := range dataUnique {
data = append(data, name)
sel.RemoveAttr(fmt.Sprintf("s:data-%s", name))
}
json := []string{}
for name := range jsonUnique {
json = append(json, name)
sel.RemoveAttr(fmt.Sprintf("s:json-%s", name))
}
dataRaw, _ := jsoniter.MarshalToString(data)

View file

@ -7,6 +7,29 @@ const initScriptTmpl = `
var __sui_data = %s;
} catch (e) { console.log('init data error:', e); }
function __sui_event_handler(event, dataKeys, jsonKeys, elm, handler) {
const data = {};
dataKeys.forEach(function (key) {
const value = elm.getAttribute("data:" + key);
data[key] = value;
})
jsonKeys.forEach(function (key) {
const value = elm.getAttribute("json:" + key);
data[key] = null;
if (value && value != "") {
try {
data[key] = JSON.parse(value);
} catch (e) {
const message = e.message || e || "An error occurred";
console.error(` + "`[SUI] Event Handler Error: ${message}`" + `, elm);
}
}
})
handler && handler(event, data, elm);
};
document.addEventListener("DOMContentLoaded", function () {
try {
document.querySelectorAll("[s\\:ready]").forEach(function (element) {
@ -42,25 +65,9 @@ const i118nScriptTmpl = `
const pageEventScriptTmpl = `
document.querySelector("[s\\:event=%s]").addEventListener("%s", function (event) {
let data = {};
const dataKeys = %s;
const jsonKeys = %s;
const elm = this;
dataKeys.forEach(function (key) {
const value = elm.getAttribute("data:" + key);
data[key] = value;
})
jsonKeys.forEach(function (key) {
const value = elm.getAttribute("json:" + key);
data[key] = null;
if (value && value != "") {
data[key] = JSON.parse(value);
}
})
%s && %s(event, data, this);
__sui_event_handler(event, dataKeys, jsonKeys, this, %s);
});
`
@ -77,5 +84,5 @@ func headInjectionScript(jsonRaw string) string {
}
func pageEventInjectScript(eventID, eventName, dataKeys, jsonKeys, handler string) string {
return fmt.Sprintf(pageEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, handler, handler)
return fmt.Sprintf(pageEventScriptTmpl, eventID, eventName, dataKeys, jsonKeys, handler)
}

View file

@ -66,13 +66,13 @@ func TestTemplatePageTree(t *testing.T) {
assert.NotEmpty(t, pages)
assert.NotEmpty(t, pages[1].Children)
if len(pages[1].Children) < 2 {
if len(pages[1].Children) < 3 {
t.Fatalf("Pages error: %v", len(pages[1].Children))
}
assert.NotEmpty(t, pages[1].Children[0].Children)
if len(pages[1].Children[0].Children) < 2 {
t.Fatalf("Pages error: %v", len(pages[1].Children[0].Children))
assert.NotEmpty(t, pages[2].Children[0].Children)
if len(pages[2].Children[0].Children) < 2 {
t.Fatalf("Pages error: %v", len(pages[2].Children[0].Children))
}
}