added a new way for native DOM <-> virtual DOM interop, see nativenodes.nim example
This commit is contained in:
parent
a90efe752d
commit
18b5a12d1e
5 changed files with 36 additions and 30 deletions
|
|
@ -1 +1,2 @@
|
|||
--path: "../karax"
|
||||
--path: ".."
|
||||
|
|
|
|||
18
experiments/nativenodes.nim
Normal file
18
experiments/nativenodes.nim
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
|
||||
include karax / prelude
|
||||
import karax / kdom
|
||||
|
||||
proc myInput: VNode =
|
||||
result = buildHtml:
|
||||
input()
|
||||
|
||||
var inp = vnodeToDom(myInput())
|
||||
|
||||
proc myAwesomeComponent(x: Node): VNode =
|
||||
result = dthunk(x)
|
||||
|
||||
proc main: VNode =
|
||||
result = myAwesomeComponent(inp)
|
||||
|
||||
setRenderer main
|
||||
|
|
@ -8,18 +8,15 @@ import macros, vdom, tables, strutils, kbase
|
|||
when defined(js):
|
||||
var
|
||||
vcomponents* = newJDict[cstring, proc(args: seq[VNode]): VNode]()
|
||||
dcomponents* = newJDict[cstring, proc(args: seq[VNode]): Node]()
|
||||
else:
|
||||
var
|
||||
vcomponents* = newTable[kstring, proc(args: seq[VNode]): VNode]()
|
||||
dcomponents* = newTable[kstring, proc(args: seq[VNode]): Node]()
|
||||
|
||||
type
|
||||
ComponentKind* {.pure.} = enum
|
||||
None,
|
||||
Tag,
|
||||
VNode,
|
||||
Node
|
||||
VNode
|
||||
|
||||
var
|
||||
allcomponents {.compileTime.} = initTable[string, ComponentKind]()
|
||||
|
|
@ -84,10 +81,8 @@ when defined(js):
|
|||
var isvirtual = ComponentKind.None
|
||||
if rettype == "VNode":
|
||||
isvirtual = ComponentKind.VNode
|
||||
elif rettype == "Node":
|
||||
isvirtual = ComponentKind.Node
|
||||
else:
|
||||
error "component must return VNode or Node", params[0]
|
||||
error "component must return VNode", params[0]
|
||||
let realName = if name.kind == nnkPostfix: name[1] else: name
|
||||
let nn = $realName
|
||||
n[0] = ident("inner" & nn)
|
||||
|
|
@ -105,26 +100,15 @@ when defined(js):
|
|||
proc pname(args: seq[VNode]): VNode =
|
||||
unpackCall
|
||||
|
||||
template dwrapper(pname, unpackCall) {.dirty.} =
|
||||
proc pname(args: seq[VNode]): Node =
|
||||
unpackCall
|
||||
|
||||
template vregister(key, val) =
|
||||
bind jdict.`[]=`
|
||||
`[]=`(vcomponents, kstring(key), val)
|
||||
|
||||
template dregister(key, val) =
|
||||
bind jdict.`[]=`
|
||||
`[]=`(dcomponents, kstring(key), val)
|
||||
|
||||
result = newTree(nnkStmtList, n)
|
||||
|
||||
if isvirtual == ComponentKind.VNode:
|
||||
result.add getAst(vwrapper(newname name, unpackCall))
|
||||
result.add getAst(vregister(newLit(nn), realName))
|
||||
else:
|
||||
result.add getAst(dwrapper(newname name, unpackCall))
|
||||
result.add getAst(dregister(newLit(nn), realName))
|
||||
allcomponents[nn] = isvirtual
|
||||
when defined(debugKaraxDsl):
|
||||
echo repr result
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ template attach(n: VNode) =
|
|||
n.dom = result
|
||||
if n.id != nil: kxi.byId[n.id] = n
|
||||
|
||||
proc applyEvents(n: VNode; kxi: KaraxInstance) =
|
||||
proc applyEvents(n: VNode) =
|
||||
let dest = n.dom
|
||||
for i in 0..<len(n.events):
|
||||
n.events[i][2] = wrapEvent(dest, n, n.events[i][0], n.events[i][1])
|
||||
|
|
@ -134,7 +134,7 @@ proc getVNodeById*(id: cstring; kxi: KaraxInstance = kxi): VNode =
|
|||
if kxi.byId.contains(id):
|
||||
result = kxi.byId[id]
|
||||
|
||||
proc vnodeToDom*(n: VNode; kxi: KaraxInstance): Node =
|
||||
proc vnodeToDom*(n: VNode; kxi: KaraxInstance = nil): Node =
|
||||
if n.kind == VNodeKind.text:
|
||||
result = document.createTextNode(n.text)
|
||||
attach n
|
||||
|
|
@ -150,7 +150,8 @@ proc vnodeToDom*(n: VNode; kxi: KaraxInstance): Node =
|
|||
attach n
|
||||
return result
|
||||
elif n.kind == VNodeKind.dthunk:
|
||||
result = callThunk(dcomponents[n.text], n)
|
||||
result = n.dom #callThunk(dcomponents[n.text], n)
|
||||
assert result != nil
|
||||
#n.key = result.key
|
||||
attach n
|
||||
return result
|
||||
|
|
@ -182,8 +183,8 @@ proc vnodeToDom*(n: VNode; kxi: KaraxInstance): Node =
|
|||
for k, v in attrs(n):
|
||||
if v != nil:
|
||||
result.setAttr(k, v)
|
||||
applyEvents(n, kxi)
|
||||
if n == kxi.toFocusV and kxi.toFocus.isNil:
|
||||
applyEvents(n)
|
||||
if kxi != nil and n == kxi.toFocusV and kxi.toFocus.isNil:
|
||||
kxi.toFocus = result
|
||||
if not n.style.isNil: applyStyle(result, n.style)
|
||||
|
||||
|
|
@ -194,7 +195,7 @@ proc same(n: VNode, e: Node; nesting = 0): bool =
|
|||
elif n.kind == VNodeKind.verbatim:
|
||||
result = true
|
||||
elif n.kind == VNodeKind.vthunk or n.kind == VNodeKind.dthunk:
|
||||
# we don't check these for now:
|
||||
# we don't check these:
|
||||
result = true
|
||||
elif toTag[n.kind] == e.nodename:
|
||||
result = true
|
||||
|
|
@ -245,11 +246,13 @@ proc eq(a, b: VNode): EqResult =
|
|||
if a.text != b.text:
|
||||
when defined(profileKarax): inc reasons[deText]
|
||||
return different # similar
|
||||
elif a.kind == VNodeKind.vthunk or a.kind == VNodeKind.dthunk:
|
||||
elif a.kind == VNodeKind.vthunk:
|
||||
if a.text != b.text: return different
|
||||
if a.len != b.len: return different
|
||||
for i in 0..<a.len:
|
||||
if eq(a[i], b[i]) == different: return different
|
||||
elif a.kind == VNodeKind.dthunk:
|
||||
return identical
|
||||
elif a.kind == VNodeKind.verbatim:
|
||||
if a.text != b.text:
|
||||
return different
|
||||
|
|
@ -302,7 +305,7 @@ proc mergeEvents(newNode, oldNode: VNode; kxi: KaraxInstance) =
|
|||
else: toEventName[k]
|
||||
d.removeEventListener(name, oldNode.events[i][2])
|
||||
shallowCopy(oldNode.events, newNode.events)
|
||||
applyEvents(oldNode, kxi)
|
||||
applyEvents(oldNode)
|
||||
|
||||
when false:
|
||||
proc printV(n: VNode; depth: cstring = "") =
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@ type
|
|||
VNodeKind* {.pure.} = enum
|
||||
text = "#text", int = "#int", bool = "#bool",
|
||||
vthunk = "#vthunk", dthunk = "#dthunk",
|
||||
component = "#component", verbatim="#verbatim",
|
||||
component = "#component", verbatim = "#verbatim",
|
||||
|
||||
html, head, title, base, link, meta, style,
|
||||
script, noscript,
|
||||
body, section, nav, article, aside,
|
||||
h1, h2, h3, h4, h5, h6,
|
||||
header, footer, address, main
|
||||
header, footer, address, main,
|
||||
|
||||
p, hr, pre, blockquote, ol, ul, li,
|
||||
dl, dt, dd,
|
||||
|
|
@ -167,8 +167,8 @@ template callThunk*(fn: typed; n: VNode): untyped =
|
|||
proc vthunk*(name: kstring; args: varargs[VNode, vn]): VNode =
|
||||
VNode(kind: VNodeKind.vthunk, text: name, index: -1, kids: @args)
|
||||
|
||||
proc dthunk*(name: kstring; args: varargs[VNode, vn]): VNode =
|
||||
VNode(kind: VNodeKind.dthunk, text: name, index: -1, kids: @args)
|
||||
proc dthunk*(dom: Node): VNode =
|
||||
VNode(kind: VNodeKind.dthunk, dom: dom)
|
||||
|
||||
proc setEventIfNoConflict(v: VNode; kind: EventKind; handler: EventHandler) =
|
||||
assert handler != nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue