vnode caching works in the toy example
This commit is contained in:
parent
fe6e4efc29
commit
8da1ac07c0
5 changed files with 76 additions and 8 deletions
|
|
@ -7,12 +7,12 @@
|
||||||
|
|
||||||
<body id="body">
|
<body id="body">
|
||||||
|
|
||||||
|
<div id="ROOT" />
|
||||||
|
|
||||||
<script type="text/javascript" src="nimcache/example.js"></script>
|
<script type="text/javascript" src="nimcache/example.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
onload(window.location.pathname.split('/')[1])
|
onload(window.location.pathname.split('/')[1])
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div id="ROOT" />
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
16
example.nim
16
example.nim
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
import vdom, karax, karaxdsl
|
import vdom, karax, karaxdsl, jdict
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
var plugins {.exportc.}: seq[(string, proc())] = @[]
|
var plugins {.exportc.}: seq[(string, proc())] = @[]
|
||||||
|
|
@ -21,15 +21,24 @@ proc onTodoEnter(val: cstring) =
|
||||||
|
|
||||||
proc onclickHandler(ev: Event; n: VNode) =
|
proc onclickHandler(ev: Event; n: VNode) =
|
||||||
let id = suffixAsInt(n.id, "remove:")
|
let id = suffixAsInt(n.id, "remove:")
|
||||||
entries.delete(id)
|
#entries.delete(id)
|
||||||
|
entries[id] = nil
|
||||||
|
|
||||||
|
var entryCache = newJDict[int, VNode]()
|
||||||
|
|
||||||
proc createEntry(i: int; d: cstring): VNode =
|
proc createEntry(i: int; d: cstring): VNode =
|
||||||
|
# implement caching:
|
||||||
|
if entryCache.contains(i):
|
||||||
|
let old = entryCache[i]
|
||||||
|
return old
|
||||||
|
|
||||||
result = buildHtml(tr) do:
|
result = buildHtml(tr) do:
|
||||||
td:
|
td:
|
||||||
text d
|
text d
|
||||||
td:
|
td:
|
||||||
span(id="remove:" & $i, onclick=onclickHandler):
|
span(id="remove:" & $i, onclick=onclickHandler):
|
||||||
text "[remove]"
|
text "[remove]"
|
||||||
|
entryCache[i] = result
|
||||||
|
|
||||||
proc createDom(): VNode =
|
proc createDom(): VNode =
|
||||||
result = buildHtml(tdiv) do:
|
result = buildHtml(tdiv) do:
|
||||||
|
|
@ -42,7 +51,8 @@ proc createDom(): VNode =
|
||||||
enterInput("todo-input", "", onTodoEnter)
|
enterInput("todo-input", "", onTodoEnter)
|
||||||
table(class = "wl"):
|
table(class = "wl"):
|
||||||
for i, d in entries:
|
for i, d in entries:
|
||||||
createEntry(i, d)
|
if d != nil:
|
||||||
|
createEntry(i, d)
|
||||||
|
|
||||||
setRenderer createDom
|
setRenderer createDom
|
||||||
|
|
||||||
|
|
|
||||||
11
jdict.nim
Normal file
11
jdict.nim
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
type
|
||||||
|
JDict*[K, V] = ref object
|
||||||
|
|
||||||
|
proc `[]`*[K, V](d: JDict[K, V], k: K): V {.importcpp: "#[#]".}
|
||||||
|
proc `[]=`*[K, V](d: JDict[K, V], k: K, v: V) {.importcpp: "#[#] = #".}
|
||||||
|
|
||||||
|
proc newJDict*[K, V](): JDict[K, V] {.importcpp: "{@}".}
|
||||||
|
|
||||||
|
proc contains*[K, V](d: JDict[K, V], k: K): bool {.importcpp: "#.hasOwnProperty(#)".}
|
||||||
|
|
||||||
|
|
@ -138,9 +138,12 @@ proc dodraw() =
|
||||||
|
|
||||||
proc redraw*() =
|
proc redraw*() =
|
||||||
# we buffer redraw requests:
|
# we buffer redraw requests:
|
||||||
if drawTimeout != nil:
|
when false:
|
||||||
clearTimeout(drawTimeout)
|
if drawTimeout != nil:
|
||||||
drawTimeout = setTimeout(dodraw, 30)
|
clearTimeout(drawTimeout)
|
||||||
|
drawTimeout = setTimeout(dodraw, 30)
|
||||||
|
else:
|
||||||
|
dodraw()
|
||||||
|
|
||||||
#proc prepend*(parent, kid: Element) =
|
#proc prepend*(parent, kid: Element) =
|
||||||
# parent.insertBefore(kid, parent.firstChild)
|
# parent.insertBefore(kid, parent.firstChild)
|
||||||
|
|
|
||||||
44
vdom.nim
44
vdom.nim
|
|
@ -39,6 +39,21 @@ type
|
||||||
proc value*(n: VNode): cstring = n.text
|
proc value*(n: VNode): cstring = n.text
|
||||||
proc `value=`*(n: VNode; v: cstring) = n.text = v
|
proc `value=`*(n: VNode; v: cstring) = n.text = v
|
||||||
|
|
||||||
|
proc eq*(a, b: VNode): bool =
|
||||||
|
if a.kind != b.kind: return false
|
||||||
|
if a.id != b.id: return false
|
||||||
|
if a.class != b.class: return false
|
||||||
|
if a.kind != VNodeKind.text:
|
||||||
|
if a.kids.len != b.kids.len: return false
|
||||||
|
for i in 0..<a.kids.len:
|
||||||
|
if not eq(a.kids[i], b.kids[i]): return false
|
||||||
|
else:
|
||||||
|
if a.text != b.text: return false
|
||||||
|
if a.attrs.len != b.attrs.len: return false
|
||||||
|
for i in 0..<a.attrs.len:
|
||||||
|
if a.attrs[i] != b.attrs[i]: return false
|
||||||
|
result = true
|
||||||
|
|
||||||
proc setAttr*(n: VNode; key: cstring; val: cstring = "") =
|
proc setAttr*(n: VNode; key: cstring; val: cstring = "") =
|
||||||
if n.attrs.isNil:
|
if n.attrs.isNil:
|
||||||
n.attrs = @[key, val]
|
n.attrs = @[key, val]
|
||||||
|
|
@ -80,3 +95,32 @@ iterator attrs*(n: VNode): (cstring, cstring) =
|
||||||
|
|
||||||
proc addEventListener*(n: VNode; event: EventKind; handler: EventHandler) =
|
proc addEventListener*(n: VNode; event: EventKind; handler: EventHandler) =
|
||||||
n.events.add((event, handler))
|
n.events.add((event, handler))
|
||||||
|
|
||||||
|
template toStringAttr(field) =
|
||||||
|
if n.field != nil:
|
||||||
|
result.add " " & astToStr(field) & " = " & $n.field
|
||||||
|
|
||||||
|
proc toString*(n: VNode; result: var string; indent: int) =
|
||||||
|
for i in 1..indent: result.add ' '
|
||||||
|
if result.len > 0: result.add '\L'
|
||||||
|
result.add "<" & $n.kind
|
||||||
|
toStringAttr(id)
|
||||||
|
toStringAttr(class)
|
||||||
|
for k, v in attrs(n):
|
||||||
|
result.add " " & $k & " = " & $v
|
||||||
|
result.add ">\L"
|
||||||
|
if n.kind == VNodeKind.text:
|
||||||
|
result.add n.text
|
||||||
|
else:
|
||||||
|
if n.text != nil:
|
||||||
|
result.add " value = "
|
||||||
|
result.add n.text
|
||||||
|
for child in items(n):
|
||||||
|
toString(child, result, indent+2)
|
||||||
|
for i in 1..indent: result.add ' '
|
||||||
|
result.add "\L</" & $n.kind & ">"
|
||||||
|
|
||||||
|
proc `$`*(n: VNode): cstring =
|
||||||
|
var res = ""
|
||||||
|
toString(n, res, 0)
|
||||||
|
result = cstring(res)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue