-
Notifications
You must be signed in to change notification settings - Fork 660
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #698 from trheyi/main
add event binding logic in SUI core
- Loading branch information
Showing
6 changed files
with
208 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package core | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/PuerkitoBio/goquery" | ||
jsoniter "github.com/json-iterator/go" | ||
"golang.org/x/net/html" | ||
) | ||
|
||
// BindEvent is a method that binds events to the page. | ||
func (page *Page) BindEvent(ctx *BuildContext, sel *goquery.Selection) { | ||
matcher := NewAttrPrefixMatcher(`s:on-`) | ||
sel.FindMatcher(matcher).Each(func(i int, s *goquery.Selection) { | ||
page.appendEventScript(ctx, s) | ||
}) | ||
} | ||
|
||
func (page *Page) appendEventScript(ctx *BuildContext, sel *goquery.Selection) { | ||
|
||
if len(sel.Nodes) == 0 { | ||
return | ||
} | ||
|
||
// Page events | ||
events := map[string]string{} | ||
dataUnique := map[string]string{} | ||
jsonUnique := map[string]string{} | ||
id := fmt.Sprintf("event-%d", ctx.sequence) | ||
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.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.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) | ||
jsonRaw, _ := jsoniter.MarshalToString(json) | ||
|
||
source := "" | ||
for name, handler := range events { | ||
source += pageEventInjectScript(id, name, dataRaw, jsonRaw, handler) + "\n" | ||
sel.RemoveAttr(fmt.Sprintf("s:on-%s", name)) | ||
} | ||
|
||
ctx.scripts = append(ctx.scripts, ScriptNode{ | ||
Source: source, | ||
Namespace: page.namespace, | ||
Attrs: []html.Attribute{{Key: "event", Val: id}}, | ||
}) | ||
|
||
sel.SetAttr("s:event", id) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package core | ||
|
||
import ( | ||
"regexp" | ||
"strings" | ||
|
||
"golang.org/x/net/html" | ||
) | ||
|
||
// AttrMatcher is a matcher that matches attribute keys | ||
type AttrMatcher struct { | ||
prefix string | ||
re *regexp.Regexp | ||
} | ||
|
||
// NewAttrPrefixMatcher creates a new attribute matcher that matches attribute keys with the given prefix | ||
func NewAttrPrefixMatcher(prefix string) *AttrMatcher { | ||
return &AttrMatcher{prefix: prefix} | ||
} | ||
|
||
// NewAttrRegexpMatcher creates a new attribute matcher that matches attribute keys with the given regexp | ||
func NewAttrRegexpMatcher(re *regexp.Regexp) *AttrMatcher { | ||
return &AttrMatcher{re: re} | ||
} | ||
|
||
// Match returns true if the node has an attribute key that matches the matcher | ||
func (m *AttrMatcher) Match(n *html.Node) bool { | ||
if m.re == nil { | ||
return m.prefixMatch(n) | ||
} | ||
return m.regexpMatch(n) | ||
} | ||
|
||
func (m *AttrMatcher) regexpMatch(n *html.Node) bool { | ||
for _, attr := range n.Attr { | ||
if m.re.MatchString(attr.Key) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func (m *AttrMatcher) prefixMatch(n *html.Node) bool { | ||
for _, attr := range n.Attr { | ||
if strings.HasPrefix(attr.Key, m.prefix) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
// MatchAll returns all the nodes that have an attribute key that matches the matcher | ||
func (m *AttrMatcher) MatchAll(n *html.Node) []*html.Node { | ||
var nodes []*html.Node | ||
for c := n.FirstChild; c != nil; c = c.NextSibling { | ||
if m.Match(c) { | ||
nodes = append(nodes, c) | ||
} | ||
nodes = append(nodes, m.MatchAll(c)...) | ||
} | ||
return nodes | ||
|
||
} | ||
|
||
// Filter returns all the nodes that have an attribute key that matches the matcher | ||
func (m *AttrMatcher) Filter(ns []*html.Node) []*html.Node { | ||
var nodes []*html.Node | ||
for _, n := range ns { | ||
if m.Match(n) { | ||
nodes = append(nodes, n) | ||
} | ||
} | ||
return nodes | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters