111 lines
2.9 KiB
Go
111 lines
2.9 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/PuerkitoBio/goquery"
|
|
jsoniter "github.com/json-iterator/go"
|
|
"golang.org/x/net/html"
|
|
)
|
|
|
|
var eventMatcher = NewAttrPrefixMatcher(`s:on-`)
|
|
|
|
// BindEvent is a method that binds events to the page.
|
|
func (page *Page) BindEvent(ctx *BuildContext, sel *goquery.Selection, cn string, ispage bool) {
|
|
|
|
sel.FindMatcher(eventMatcher).Each(func(i int, s *goquery.Selection) {
|
|
if comp, has := s.Attr("is"); has && ctx.isJitComponent(comp) {
|
|
return
|
|
}
|
|
script := GetEventScript(ctx.sequence, s, page.namespace, cn, "event", ispage)
|
|
if script != nil {
|
|
ctx.scripts = append(ctx.scripts, *script)
|
|
ctx.sequence++
|
|
}
|
|
})
|
|
}
|
|
|
|
// BindEvent is a method that binds events to the component in just-in-time mode.
|
|
func (parser *TemplateParser) BindEvent(sel *goquery.Selection, ns string, cn string) {
|
|
sel.FindMatcher(eventMatcher).Each(func(i int, s *goquery.Selection) {
|
|
script := GetEventScript(parser.sequence, s, ns, cn, "event-jit", false)
|
|
if script != nil {
|
|
script.Component = ""
|
|
script.Parent = "body"
|
|
parser.scripts = append(parser.scripts, *script)
|
|
parser.sequence++
|
|
}
|
|
})
|
|
}
|
|
|
|
// GetEventScript the event script
|
|
func GetEventScript(sequence int, sel *goquery.Selection, ns string, cn string, prefix string, ispage bool) *ScriptNode {
|
|
|
|
if len(sel.Nodes) == 0 {
|
|
return nil
|
|
}
|
|
|
|
// Page events
|
|
events := map[string]string{}
|
|
dataUnique := map[string]string{}
|
|
jsonUnique := map[string]string{}
|
|
id := fmt.Sprintf("%s-%d", prefix, 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 {
|
|
if ispage {
|
|
source += pageEventInjectScript(id, name, dataRaw, jsonRaw, handler) + "\n"
|
|
} else {
|
|
source += compEventInjectScript(id, name, cn, dataRaw, jsonRaw, handler) + "\n"
|
|
}
|
|
sel.RemoveAttr(fmt.Sprintf("s:on-%s", name))
|
|
}
|
|
|
|
sel.SetAttr("s:event", id)
|
|
|
|
return &ScriptNode{
|
|
Source: source,
|
|
Namespace: ns,
|
|
Component: cn,
|
|
Attrs: []html.Attribute{{Key: "event", Val: id}},
|
|
}
|
|
}
|