Fix the bug in real-time rendering mode
This commit is contained in:
parent
0a21780473
commit
fb6518e91f
7 changed files with 174 additions and 86 deletions
120
data/bindata.go
120
data/bindata.go
File diff suppressed because one or more lines are too long
|
|
@ -256,13 +256,37 @@ func (script ScriptNode) ComponentHTML(ns string) string {
|
|||
return "<script " + strings.Join(attrs, " ") + "></script>"
|
||||
}
|
||||
|
||||
source := fmt.Sprintf(`function %s(){%s};`, script.Component, script.Source)
|
||||
source := script.Source
|
||||
if !strings.Contains(script.Source, "function "+script.Component) {
|
||||
source = fmt.Sprintf(`function %s(){%s};`, script.Component, script.Source)
|
||||
}
|
||||
|
||||
if script.Component == "" {
|
||||
return "<script " + strings.Join(attrs, " ") + ">\n" + script.Source + "\n</script>"
|
||||
}
|
||||
return "<script " + strings.Join(attrs, " ") + ">\n" + source + "\n</script>"
|
||||
}
|
||||
|
||||
// AttrOr return the attribute value or the default value
|
||||
func (script ScriptNode) AttrOr(key string, or string) string {
|
||||
for _, attr := range script.Attrs {
|
||||
if attr.Key == key {
|
||||
return attr.Val
|
||||
}
|
||||
}
|
||||
return or
|
||||
}
|
||||
|
||||
// AttrOr return the attribute value or the default value
|
||||
func (style StyleNode) AttrOr(key string, or string) string {
|
||||
for _, attr := range style.Attrs {
|
||||
if attr.Key == key {
|
||||
return attr.Val
|
||||
}
|
||||
}
|
||||
return or
|
||||
}
|
||||
|
||||
// HTML return the html of the style node
|
||||
func (style StyleNode) HTML() string {
|
||||
attrs := []string{
|
||||
|
|
|
|||
|
|
@ -50,27 +50,19 @@ const initScriptTmpl = `
|
|||
} catch (e) { console.log('init data error:', e); }
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
try {
|
||||
document.querySelectorAll("[s\\:ready]").forEach(function (element) {
|
||||
const method = element.getAttribute("s:ready");
|
||||
const cn = element.getAttribute("s:cn");
|
||||
if (method && typeof window[cn] === "function") {
|
||||
try {
|
||||
new window[cn](element);
|
||||
} catch (e) {
|
||||
const message = e.message || e || "An error occurred";
|
||||
console.error(` + "`[SUI] ${cn} Error: ${message}`" + `);
|
||||
}
|
||||
document.querySelectorAll("[s\\:ready]").forEach(function (element) {
|
||||
const method = element.getAttribute("s:ready");
|
||||
const cn = element.getAttribute("s:cn");
|
||||
if (method && typeof window[cn] === "function") {
|
||||
try {
|
||||
new window[cn](element);
|
||||
} catch (e) {
|
||||
const message = e.message || e || "An error occurred";
|
||||
console.error(` + "`[SUI] ${cn} Error: ${message}`" + `);
|
||||
}
|
||||
});
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
__sui_event_init(document.body);
|
||||
} catch (e) {
|
||||
const message = e.message || e || "An error occurred";
|
||||
console.error(` + "`[SUI] ${cn} Error: ${message}`" + `);
|
||||
}
|
||||
}
|
||||
});
|
||||
__sui_event_init(document.body);
|
||||
});
|
||||
%s
|
||||
`
|
||||
|
|
|
|||
|
|
@ -65,6 +65,42 @@ func (parser *TemplateParser) parseJitComponent(sel *goquery.Selection) {
|
|||
}
|
||||
parser.parseElementComponent(comsel)
|
||||
sel.ReplaceWithSelection(comsel)
|
||||
|
||||
if len(comp.scripts) == 0 && len(comp.styles) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if parser.context == nil {
|
||||
parser.context = &ParserContext{
|
||||
scripts: []ScriptNode{},
|
||||
styles: []StyleNode{},
|
||||
scriptMaps: map[string]bool{},
|
||||
styleMaps: map[string]bool{},
|
||||
}
|
||||
}
|
||||
|
||||
// Add the scripts
|
||||
if comp.scripts != nil {
|
||||
for _, script := range comp.scripts {
|
||||
if parser.context.scriptMaps[script.Component] {
|
||||
continue
|
||||
}
|
||||
script.Parent = "head"
|
||||
parser.context.scriptMaps[script.Component] = true
|
||||
parser.context.scripts = append(parser.context.scripts, script)
|
||||
}
|
||||
}
|
||||
|
||||
// Add the styles
|
||||
if comp.styles != nil {
|
||||
for _, style := range comp.styles {
|
||||
if parser.context.styleMaps[style.Component] {
|
||||
continue
|
||||
}
|
||||
parser.context.styles = append(parser.context.styles, style)
|
||||
parser.context.styleMaps[style.Component] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (parser *TemplateParser) newJitComponentSel(sel *goquery.Selection, comp *JitComponent) (*goquery.Selection, error) {
|
||||
|
|
@ -325,6 +361,15 @@ func (parser *TemplateParser) addScripts(sel *goquery.Selection, scripts []Scrip
|
|||
continue
|
||||
}
|
||||
}
|
||||
|
||||
src := script.AttrOr("src", "")
|
||||
if src != "" {
|
||||
query := fmt.Sprintf(`script[src="%s"]`, src)
|
||||
if sel.Find(query).Length() > 0 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
sel.AppendHtml(script.ComponentHTML(script.Namespace))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ type TemplateParser struct {
|
|||
|
||||
// ParserContext parser context for the template
|
||||
type ParserContext struct {
|
||||
scriptMaps map[string]bool // parsed components
|
||||
styleMaps map[string]bool // parsed styles
|
||||
scripts []ScriptNode // scripts
|
||||
styles []StyleNode // styles
|
||||
}
|
||||
|
||||
// Mapping mapping for the template
|
||||
|
|
@ -147,6 +151,17 @@ func (parser *TemplateParser) Render(html string) (string, error) {
|
|||
head.AppendHtml(headInjectionScript(data))
|
||||
parser.addScripts(head, parser.filterScripts("head", parser.scripts))
|
||||
parser.addStyles(head, parser.styles)
|
||||
|
||||
// Append the just-in-time components
|
||||
if parser.context != nil {
|
||||
if parser.context.scripts != nil && len(parser.context.scripts) > 0 {
|
||||
parser.addScripts(head, parser.filterScripts("head", parser.context.scripts))
|
||||
}
|
||||
if parser.context.scripts != nil && len(parser.context.styles) > 0 {
|
||||
parser.addStyles(head, parser.context.styles)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Append the data to the body
|
||||
|
|
@ -158,6 +173,11 @@ func (parser *TemplateParser) Render(html string) (string, error) {
|
|||
}
|
||||
body.AppendHtml(bodyInjectionScript(data, parser.debug()))
|
||||
parser.addScripts(body, parser.filterScripts("body", parser.scripts))
|
||||
|
||||
// Append the just-in-time components
|
||||
if parser.context != nil && len(parser.context.scripts) > 0 {
|
||||
parser.addScripts(body, parser.filterScripts("body", parser.context.scripts))
|
||||
}
|
||||
}
|
||||
|
||||
// For editor
|
||||
|
|
@ -340,6 +360,7 @@ func (parser *TemplateParser) parseElementComponent(sel *goquery.Selection) {
|
|||
setError(sel, err)
|
||||
}
|
||||
parser.sequence = compParser.sequence + 1
|
||||
parser.context = compParser.context
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,11 +71,12 @@ func ComponentName(name string, hash ...bool) string {
|
|||
name = strings.ReplaceAll(name, "[", "_")
|
||||
name = strings.ReplaceAll(name, "]", "_")
|
||||
cn := fmt.Sprintf("comp_%s", name)
|
||||
if len(hash) > 0 && hash[0] {
|
||||
h := fnv.New64a()
|
||||
h.Write([]byte(cn))
|
||||
return fmt.Sprintf("cn_%x", h.Sum64())
|
||||
}
|
||||
// Keep the component name | hash will be supported later
|
||||
// if len(hash) > 0 && hash[0] {
|
||||
// h := fnv.New64a()
|
||||
// h.Write([]byte(cn))
|
||||
// return fmt.Sprintf("cn_%x", h.Sum64())
|
||||
// }
|
||||
return cn
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,11 @@ function __sui_event_init(elm: Element) {
|
|||
}
|
||||
|
||||
const component = eventElm.closest(`[s\\:cn=${cn}]`);
|
||||
if (typeof window[cn] !== "function") {
|
||||
console.error(`[SUI] Component ${cn} not found`, eventElm);
|
||||
return;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
const comp = new window[cn](component);
|
||||
const handler = comp[bind];
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue