-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathspago.go
114 lines (102 loc) · 2.07 KB
/
spago.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package spago
import (
"fmt"
"syscall/js"
)
var (
global = js.Global()
document = global.Get("document")
console = js.Global().Get("console")
mounts []Mounter
// VerboseMode ...
VerboseMode bool
)
// Tag markup
func Tag(tag string, markups ...Markup) *Node {
t := &Node{tag: tag, classmap: ClassMap{}}
for _, m := range markups {
m.apply(t)
}
return t
}
// TagNS markup
func TagNS(namespace, tag string, markups ...Markup) *Node {
t := &Node{namespace: namespace, tag: tag, classmap: ClassMap{}}
for _, m := range markups {
m.apply(t)
}
return t
}
// Render ...
func render(old js.Value, c Component) {
core := c.get()
if v, ok := c.(Unmounter); !core.target.IsUndefined() && ok {
v.Unmount()
}
core.target = c.Render().html(true)
for _, v := range expandNodes(core.target) {
old.Get("parentNode").Call("replaceChild", v, old)
}
if v := old.Get("release"); !v.IsUndefined() {
v.Invoke()
}
//old.Call("remove")
}
func mount() {
for _, v := range mounts {
v.Mount()
}
mounts = nil
}
var lastComponent = map[string]Component{}
// Render ...
func Render(q string, c Component) {
e := document.Call("querySelector", q)
if e.IsUndefined() {
panic(fmt.Sprintf("not found element: %q", q))
}
if v, ok := lastComponent[q].(Unmounter); ok {
v.Unmount()
}
render(e, c)
if v, ok := c.(Mounter); ok {
mounts = append(mounts, v)
}
lastComponent[q] = c
mount()
}
var lastBody Component
// RenderBody ...
func RenderBody(c Component) {
if v, ok := lastBody.(Unmounter); ok {
v.Unmount()
}
render(document.Get("body"), c)
if v, ok := c.(Mounter); ok {
mounts = append(mounts, v)
}
lastBody = c
mount()
}
// Rerender ...
func Rerender(c Component) {
core := c.get()
old := core.target
if old.IsNull() {
panic(fmt.Sprint("this component rendering not yet:", c))
}
if v, ok := c.(Unmounter); ok {
v.Unmount()
}
next := c.Render().html(true)
var patch Patches
for _, v := range expandNodes(next) {
patch = append(patch, Diff(old, v)...)
v.Call("release")
}
patch.Do()
if v, ok := c.(Mounter); ok {
mounts = append(mounts, v)
}
mount()
}