diff --git a/experiments/refs/demo.html b/experiments/refs/demo.html
new file mode 100644
index 0000000..e1fe419
--- /dev/null
+++ b/experiments/refs/demo.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ Refs
+
+
+
+
+
+
+
diff --git a/experiments/refs/demo.nim b/experiments/refs/demo.nim
new file mode 100644
index 0000000..dffb1e9
--- /dev/null
+++ b/experiments/refs/demo.nim
@@ -0,0 +1,39 @@
+include karaxprelude
+import random
+
+var
+ modelData = @[5, 2, 4]
+
+ refA = VNodeRef()
+ refB = VNodeRef()
+ refSeq = newSeq[VNodeRef]()
+
+proc onClick(ev: Event, n: VNode) =
+ kout(refA)
+ kout(refB)
+ kout(refSeq)
+
+proc secureRefSlot(i: int): VNodeRef =
+ while refSeq.len <= i:
+ refSeq.add(VNodeRef())
+ result = refSeq[i]
+
+proc view(): VNode =
+ result = buildHtml():
+ tdiv:
+ button(onclick=onClick):
+ text "click me"
+ # storing refs to single elements is straightforward now
+ tdiv(nref=refA):
+ text "A"
+ tdiv(nref=refB):
+ text "B"
+ # It's a bit more tricky when containers are involved:
+ for i, x in modelData.pairs:
+ tdiv(nref=secureRefSlot(i)):
+ text "List item: " & $x
+
+proc renderer(): VNode =
+ view()
+
+setRenderer renderer
diff --git a/experiments/refs/demo.nims b/experiments/refs/demo.nims
new file mode 100644
index 0000000..9028ff1
--- /dev/null
+++ b/experiments/refs/demo.nims
@@ -0,0 +1 @@
+--path: "../../src"
diff --git a/src/karax.nim b/src/karax.nim
index cc52e2f..d8a4cb1 100644
--- a/src/karax.nim
+++ b/src/karax.nim
@@ -65,8 +65,14 @@ proc wrapEvent(d: Node; n: VNode; k: EventKind; action: EventHandler) =
# --------------------- DOM diff -----------------------------------------
-template detach(n: VNode) = n.dom = nil
-template attach(n: Vnode) = n.dom = result
+template detach(n: VNode) =
+ if not n.nref.isNil():
+ n.nref.vnode = nil
+ n.dom = nil
+template attach(n: VNode) =
+ if not n.nref.isNil():
+ n.nref.vnode = n
+ n.dom = result
proc vnodeToDom(n: VNode): Node =
if n.kind == VNodeKind.text:
diff --git a/src/karaxdsl.nim b/src/karaxdsl.nim
index 190545c..8693f5b 100644
--- a/src/karaxdsl.nim
+++ b/src/karaxdsl.nim
@@ -4,7 +4,7 @@ from strutils import startsWith, toLowerAscii
const
StmtContext = ["kout", "inc", "echo", "dec", "!"]
- SpecialAttrs = ["id", "class", "value", "key", "style"]
+ SpecialAttrs = ["id", "class", "value", "key", "style", "nref"]
proc getName(n: NimNode): string =
case n.kind
diff --git a/src/vdom.nim b/src/vdom.nim
index d55e7b4..f4ccff8 100644
--- a/src/vdom.nim
+++ b/src/vdom.nim
@@ -101,6 +101,9 @@ macro buildLookupTables(): untyped =
buildLookupTables()
type
+ VNodeRef* = ref object
+ vnode*: VNode
+
EventHandler* = proc (ev: Event; target: VNode) {.closure.}
VKey* = int
@@ -108,6 +111,7 @@ type
kind*: VNodeKind
key*: VKey
id*, class*, text*: cstring
+ nref*: VNodeRef
kids: seq[VNode]
# even index: key, odd index: value; done this way for memory efficiency:
attrs: seq[cstring]