From 93d36b7f036aac1258a7e1ce29c6322922c11965 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 28 Jul 2024 17:55:47 +0800 Subject: [PATCH 1/3] Optimize SUI core to parse imports and set namespace attribute --- sui/core/build.go | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/sui/core/build.go b/sui/core/build.go index 153b0adb..e092f986 100644 --- a/sui/core/build.go +++ b/sui/core/build.go @@ -52,8 +52,12 @@ func (page *Page) Build(ctx *BuildContext, option *BuildOption) (*goquery.Docume if err != nil { return nil, ctx.warnings, err } - doc.Find("body").SetAttr("s:ns", namespace) + // Parse the imports + page.parseImports(doc) + + body := doc.Find("body") + body.SetAttr("s:ns", namespace) // Bind the Page events if !option.JitMode { page.BindEvent(ctx, doc.Selection, "__page", true) @@ -172,6 +176,9 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op return "", err } + // Parse the imports + page.parseImports(doc) + // Bind the component events page.BindEvent(ctx, doc.Selection, component, false) @@ -240,6 +247,30 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op return source, nil } +func (page *Page) parseImports(doc *goquery.Document) { + imports := doc.Find("s\\:import") + mapping := map[string]string{} + for i := 0; i < imports.Length(); i++ { + name := imports.Eq(i).AttrOr("name", "") + from := imports.Eq(i).AttrOr("from", "") + if name == "" || from == "" { + continue + } + mapping[name] = from + imports.Eq(i).Remove() + } + + // Add the is attr to the import tag + for name, from := range mapping { + selectors := doc.Find(name) + for i := 0; i < selectors.Length(); i++ { + if _, has := selectors.Eq(i).Attr("is"); !has { + selectors.Eq(i).SetAttr("is", from) + } + } + } +} + func (page *Page) copySlots(from *goquery.Selection, to *goquery.Selection) error { slots := from.Find("slot") if slots.Length() == 0 { From 1763a4f2e7ccf49fc1550d3cd54cbb3ac85117e5 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 28 Jul 2024 19:16:02 +0800 Subject: [PATCH 2/3] feat: Support component import and aliasing in SUI --- sui/core/build.go | 92 ++++++++++++++++++++++++++++++++++++++++------- sui/core/types.go | 7 ++++ 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/sui/core/build.go b/sui/core/build.go index e092f986..9dcd1978 100644 --- a/sui/core/build.go +++ b/sui/core/build.go @@ -249,26 +249,92 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op func (page *Page) parseImports(doc *goquery.Document) { imports := doc.Find("s\\:import") - mapping := map[string]string{} + mapping := map[string]PageImport{} for i := 0; i < imports.Length(); i++ { - name := imports.Eq(i).AttrOr("name", "") - from := imports.Eq(i).AttrOr("from", "") + defer imports.Eq(i).Remove() + name := imports.Eq(i).AttrOr("s:name", "") + from := imports.Eq(i).AttrOr("s:from", "") if name == "" || from == "" { continue } - mapping[name] = from - imports.Eq(i).Remove() - } - - // Add the is attr to the import tag - for name, from := range mapping { - selectors := doc.Find(name) - for i := 0; i < selectors.Length(); i++ { - if _, has := selectors.Eq(i).Attr("is"); !has { - selectors.Eq(i).SetAttr("is", from) + if _, has := mapping[name]; has { + continue + } + mapping[name] = PageImport{ + is: from, + selection: imports.Eq(i).Clone(), + slots: map[string]*goquery.Selection{}, + } + slots := mapping[name].selection.Find("slot") + if slots.Length() > 0 { + for j := 0; j < slots.Length(); j++ { + slot := slots.Eq(j) + slotName, has := slot.Attr("name") + if !has { + continue + } + mapping[name].slots[slotName] = slot.Contents().Clone() + slot.Remove() } } } + + // Merge the imports + for name, imp := range mapping { + selections := doc.Find(name) + if selections.Length() == 0 { + continue + } + + for i := 0; i < selections.Length(); i++ { + selection := selections.Eq(i) + if _, has := selection.Attr("is"); has { + continue + } + + // Copy the attributes + selection.SetAttr("is", imp.is) + for _, attr := range imp.selection.Get(0).Attr { + if strings.HasPrefix(attr.Key, "s:") { + continue + } + + if _, has := selection.Attr(attr.Key); !has { + selection.SetAttr(attr.Key, attr.Val) + } + } + + // Copy the slots + slots := selection.Find("slot").Clone() + for i = 0; i < slots.Length(); i++ { + slot := slots.Eq(i) + slotName, has := slot.Attr("name") + if !has { + continue + } + if impSlot, has := imp.slots[slotName]; has { + impSlot.ReplaceWithSelection(slot) + } + } + + // Copy the children + children := selection.Contents().Clone() + children.Find("slot").Remove() + if children.Length() == 0 { + children = imp.selection.Clone() + } + + // Append the children + selection.Contents().Remove() + selection.AppendSelection(children) + + // Append the slots + for _, slot := range imp.slots { + selection.AppendSelection(slot) + } + } + } + } func (page *Page) copySlots(from *goquery.Selection, to *goquery.Selection) error { diff --git a/sui/core/types.go b/sui/core/types.go index 3ebf9f29..038e37d0 100644 --- a/sui/core/types.go +++ b/sui/core/types.go @@ -74,6 +74,13 @@ type BuildContext struct { stack []string // Stack to manage build states } +// PageImport import instance +type PageImport struct { + is string + selection *goquery.Selection + slots map[string]*goquery.Selection +} + // TranslateContext is the struct for the translate context type TranslateContext struct { sequence int From 4c5278938c812c485f525686ece2e93883628f8b Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 28 Jul 2024 19:27:16 +0800 Subject: [PATCH 3/3] Refactor SUI core to improve import parsing and aliasing --- sui/core/build.go | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sui/core/build.go b/sui/core/build.go index 9dcd1978..7c02c487 100644 --- a/sui/core/build.go +++ b/sui/core/build.go @@ -248,15 +248,15 @@ func (page *Page) BuildAsComponent(sel *goquery.Selection, ctx *BuildContext, op } func (page *Page) parseImports(doc *goquery.Document) { - imports := doc.Find("s\\:import") + imports := doc.Find("import") mapping := map[string]PageImport{} for i := 0; i < imports.Length(); i++ { - defer imports.Eq(i).Remove() - name := imports.Eq(i).AttrOr("s:name", "") + name := imports.Eq(i).AttrOr("s:as", "") from := imports.Eq(i).AttrOr("s:from", "") if name == "" || from == "" { continue } + defer imports.Eq(i).Remove() if _, has := mapping[name]; has { continue } @@ -295,10 +295,9 @@ func (page *Page) parseImports(doc *goquery.Document) { // Copy the attributes selection.SetAttr("is", imp.is) for _, attr := range imp.selection.Get(0).Attr { - if strings.HasPrefix(attr.Key, "s:") { + if attr.Key == "s:as" || attr.Key == "s:from" { continue } - if _, has := selection.Attr(attr.Key); !has { selection.SetAttr(attr.Key, attr.Val) }