Merge pull request #750 from trheyi/main
Fix the bug in real-time rendering mode
This commit is contained in:
commit
56ef909662
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>"
|
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 == "" {
|
if script.Component == "" {
|
||||||
return "<script " + strings.Join(attrs, " ") + ">\n" + script.Source + "\n</script>"
|
return "<script " + strings.Join(attrs, " ") + ">\n" + script.Source + "\n</script>"
|
||||||
}
|
}
|
||||||
return "<script " + strings.Join(attrs, " ") + ">\n" + 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
|
// HTML return the html of the style node
|
||||||
func (style StyleNode) HTML() string {
|
func (style StyleNode) HTML() string {
|
||||||
attrs := []string{
|
attrs := []string{
|
||||||
|
|
|
||||||
|
|
@ -50,27 +50,19 @@ const initScriptTmpl = `
|
||||||
} catch (e) { console.log('init data error:', e); }
|
} catch (e) { console.log('init data error:', e); }
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
try {
|
document.querySelectorAll("[s\\:ready]").forEach(function (element) {
|
||||||
document.querySelectorAll("[s\\:ready]").forEach(function (element) {
|
const method = element.getAttribute("s:ready");
|
||||||
const method = element.getAttribute("s:ready");
|
const cn = element.getAttribute("s:cn");
|
||||||
const cn = element.getAttribute("s:cn");
|
if (method && typeof window[cn] === "function") {
|
||||||
if (method && typeof window[cn] === "function") {
|
try {
|
||||||
try {
|
new window[cn](element);
|
||||||
new window[cn](element);
|
} catch (e) {
|
||||||
} catch (e) {
|
const message = e.message || e || "An error occurred";
|
||||||
const message = e.message || e || "An error occurred";
|
console.error(` + "`[SUI] ${cn} Error: ${message}`" + `);
|
||||||
console.error(` + "`[SUI] ${cn} Error: ${message}`" + `);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
} catch (e) {}
|
});
|
||||||
|
__sui_event_init(document.body);
|
||||||
try {
|
|
||||||
__sui_event_init(document.body);
|
|
||||||
} catch (e) {
|
|
||||||
const message = e.message || e || "An error occurred";
|
|
||||||
console.error(` + "`[SUI] ${cn} Error: ${message}`" + `);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
%s
|
%s
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,42 @@ func (parser *TemplateParser) parseJitComponent(sel *goquery.Selection) {
|
||||||
}
|
}
|
||||||
parser.parseElementComponent(comsel)
|
parser.parseElementComponent(comsel)
|
||||||
sel.ReplaceWithSelection(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) {
|
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
|
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))
|
sel.AppendHtml(script.ComponentHTML(script.Namespace))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ type TemplateParser struct {
|
||||||
|
|
||||||
// ParserContext parser context for the template
|
// ParserContext parser context for the template
|
||||||
type ParserContext struct {
|
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
|
// Mapping mapping for the template
|
||||||
|
|
@ -147,6 +151,17 @@ func (parser *TemplateParser) Render(html string) (string, error) {
|
||||||
head.AppendHtml(headInjectionScript(data))
|
head.AppendHtml(headInjectionScript(data))
|
||||||
parser.addScripts(head, parser.filterScripts("head", parser.scripts))
|
parser.addScripts(head, parser.filterScripts("head", parser.scripts))
|
||||||
parser.addStyles(head, parser.styles)
|
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
|
// Append the data to the body
|
||||||
|
|
@ -158,6 +173,11 @@ func (parser *TemplateParser) Render(html string) (string, error) {
|
||||||
}
|
}
|
||||||
body.AppendHtml(bodyInjectionScript(data, parser.debug()))
|
body.AppendHtml(bodyInjectionScript(data, parser.debug()))
|
||||||
parser.addScripts(body, parser.filterScripts("body", parser.scripts))
|
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
|
// For editor
|
||||||
|
|
@ -340,6 +360,7 @@ func (parser *TemplateParser) parseElementComponent(sel *goquery.Selection) {
|
||||||
setError(sel, err)
|
setError(sel, err)
|
||||||
}
|
}
|
||||||
parser.sequence = compParser.sequence + 1
|
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, "[", "_")
|
||||||
name = strings.ReplaceAll(name, "]", "_")
|
name = strings.ReplaceAll(name, "]", "_")
|
||||||
cn := fmt.Sprintf("comp_%s", name)
|
cn := fmt.Sprintf("comp_%s", name)
|
||||||
if len(hash) > 0 && hash[0] {
|
// Keep the component name | hash will be supported later
|
||||||
h := fnv.New64a()
|
// if len(hash) > 0 && hash[0] {
|
||||||
h.Write([]byte(cn))
|
// h := fnv.New64a()
|
||||||
return fmt.Sprintf("cn_%x", h.Sum64())
|
// h.Write([]byte(cn))
|
||||||
}
|
// return fmt.Sprintf("cn_%x", h.Sum64())
|
||||||
|
// }
|
||||||
return cn
|
return cn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,11 @@ function __sui_event_init(elm: Element) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const component = eventElm.closest(`[s\\:cn=${cn}]`);
|
const component = eventElm.closest(`[s\\:cn=${cn}]`);
|
||||||
|
if (typeof window[cn] !== "function") {
|
||||||
|
console.error(`[SUI] Component ${cn} not found`, eventElm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const comp = new window[cn](component);
|
const comp = new window[cn](component);
|
||||||
const handler = comp[bind];
|
const handler = comp[bind];
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue