From bafe3bb20f2a2c7a3799f667b6e4b8d8c6f8df9c Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 20 Jul 2024 09:44:58 +0800 Subject: [PATCH] Refactor event binding logic in SUI core --- sui/core/build.go | 12 ++++++--- sui/core/event.go | 14 ++++++----- sui/core/injections.go | 43 +++++++++++++++++++-------------- sui/storages/local/page_test.go | 8 +++--- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/sui/core/build.go b/sui/core/build.go index d3c9972a..0009c90c 100644 --- a/sui/core/build.go +++ b/sui/core/build.go @@ -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 } diff --git a/sui/core/event.go b/sui/core/event.go index 214caebb..c959da48 100644 --- a/sui/core/event.go +++ b/sui/core/event.go @@ -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) diff --git a/sui/core/injections.go b/sui/core/injections.go index 6debf851..14eb5447 100644 --- a/sui/core/injections.go +++ b/sui/core/injections.go @@ -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) } diff --git a/sui/storages/local/page_test.go b/sui/storages/local/page_test.go index 62782835..e632b40a 100644 --- a/sui/storages/local/page_test.go +++ b/sui/storages/local/page_test.go @@ -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)) } }