fixes #35
This commit is contained in:
parent
ba88fb9a0b
commit
0ad9d68c81
3 changed files with 34 additions and 11 deletions
|
|
@ -48,8 +48,9 @@ template keyeventBody() =
|
||||||
# Do not call redraw() here! That is already done
|
# Do not call redraw() here! That is already done
|
||||||
# by ``karax.addEventHandler``.
|
# by ``karax.addEventHandler``.
|
||||||
|
|
||||||
proc wrapEvent(d: Node; n: VNode; k: EventKind; action: EventHandler) =
|
proc wrapEvent(d: Node; n: VNode; k: EventKind;
|
||||||
proc stdWrapper(): (proc (ev: Event)) =
|
action: EventHandler): NativeEventHandler =
|
||||||
|
proc stdWrapper(): NativeEventHandler =
|
||||||
let action = action
|
let action = action
|
||||||
let n = n
|
let n = n
|
||||||
result = proc (ev: Event) =
|
result = proc (ev: Event) =
|
||||||
|
|
@ -57,13 +58,13 @@ proc wrapEvent(d: Node; n: VNode; k: EventKind; action: EventHandler) =
|
||||||
keyeventBody()
|
keyeventBody()
|
||||||
else: action(ev, n)
|
else: action(ev, n)
|
||||||
|
|
||||||
proc enterWrapper(): (proc (ev: Event)) =
|
proc enterWrapper(): NativeEventHandler =
|
||||||
let action = action
|
let action = action
|
||||||
let n = n
|
let n = n
|
||||||
result = proc (ev: Event) =
|
result = proc (ev: Event) =
|
||||||
if ev.keyCode == 13: keyeventBody()
|
if ev.keyCode == 13: keyeventBody()
|
||||||
|
|
||||||
proc laterWrapper(): (proc (ev: Event)) =
|
proc laterWrapper(): NativeEventHandler =
|
||||||
let action = action
|
let action = action
|
||||||
let n = n
|
let n = n
|
||||||
var timer: Timeout
|
var timer: Timeout
|
||||||
|
|
@ -74,11 +75,14 @@ proc wrapEvent(d: Node; n: VNode; k: EventKind; action: EventHandler) =
|
||||||
|
|
||||||
case k
|
case k
|
||||||
of EventKind.onkeyuplater:
|
of EventKind.onkeyuplater:
|
||||||
d.addEventListener("keyup", laterWrapper())
|
result = laterWrapper()
|
||||||
|
d.addEventListener("keyup", result)
|
||||||
of EventKind.onkeyupenter:
|
of EventKind.onkeyupenter:
|
||||||
d.addEventListener("keyup", enterWrapper())
|
result = enterWrapper()
|
||||||
|
d.addEventListener("keyup", result)
|
||||||
else:
|
else:
|
||||||
d.addEventListener(toEventName[k], stdWrapper())
|
result = stdWrapper()
|
||||||
|
d.addEventListener(toEventName[k], result)
|
||||||
|
|
||||||
# --------------------- DOM diff -----------------------------------------
|
# --------------------- DOM diff -----------------------------------------
|
||||||
|
|
||||||
|
|
@ -90,6 +94,11 @@ template detach(n: VNode) =
|
||||||
template attach(n: VNode) =
|
template attach(n: VNode) =
|
||||||
n.dom = result
|
n.dom = result
|
||||||
|
|
||||||
|
proc applyEvents(n: VNode; kxi: KaraxInstance) =
|
||||||
|
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])
|
||||||
|
|
||||||
proc vnodeToDom(n: VNode; kxi: KaraxInstance): Node =
|
proc vnodeToDom(n: VNode; kxi: KaraxInstance): Node =
|
||||||
if n.kind == VNodeKind.text:
|
if n.kind == VNodeKind.text:
|
||||||
result = document.createTextNode(n.text)
|
result = document.createTextNode(n.text)
|
||||||
|
|
@ -132,8 +141,7 @@ proc vnodeToDom(n: VNode; kxi: KaraxInstance): Node =
|
||||||
for k, v in attrs(n):
|
for k, v in attrs(n):
|
||||||
if v != nil:
|
if v != nil:
|
||||||
result.setAttr(k, v)
|
result.setAttr(k, v)
|
||||||
for e, h in items(n.events):
|
applyEvents(n, kxi)
|
||||||
wrapEvent(result, n, e, h)
|
|
||||||
if n == kxi.toFocusV and kxi.toFocus.isNil:
|
if n == kxi.toFocusV and kxi.toFocus.isNil:
|
||||||
kxi.toFocus = result
|
kxi.toFocus = result
|
||||||
if not n.style.isNil: applyStyle(result, n.style)
|
if not n.style.isNil: applyStyle(result, n.style)
|
||||||
|
|
@ -191,6 +199,17 @@ proc updateStyles(newNode, oldNode: VNode) =
|
||||||
else: oldNode.dom.style = Style()
|
else: oldNode.dom.style = Style()
|
||||||
oldNode.style = newNode.style
|
oldNode.style = newNode.style
|
||||||
|
|
||||||
|
proc mergeEvents(newNode, oldNode: VNode) =
|
||||||
|
let d = oldNode.dom
|
||||||
|
for i in 0..<oldNode.events.len:
|
||||||
|
let k = oldNode.events[i][0]
|
||||||
|
let name = case k
|
||||||
|
of EventKind.onkeyuplater, EventKind.onkeyupenter: cstring"keyup"
|
||||||
|
else: toEventName[k]
|
||||||
|
d.removeEventListener(name, oldNode.events[i][2])
|
||||||
|
shallowCopy(oldNode.events, newNode.events)
|
||||||
|
applyEvents(oldNode, kxi)
|
||||||
|
|
||||||
proc printV(n: VNode; depth: cstring = "") =
|
proc printV(n: VNode; depth: cstring = "") =
|
||||||
kout depth, cstring($n.kind), cstring"key ", n.key
|
kout depth, cstring($n.kind), cstring"key ", n.key
|
||||||
#for k, v in pairs(n.style):
|
#for k, v in pairs(n.style):
|
||||||
|
|
@ -240,6 +259,8 @@ proc diff(newNode, oldNode: VNode;parent, current: Node; patches: JSeq[Patch]):
|
||||||
of identical, similar:
|
of identical, similar:
|
||||||
newNode.dom = oldNode.dom
|
newNode.dom = oldNode.dom
|
||||||
if result == similar: updateStyles(newNode, oldNode)
|
if result == similar: updateStyles(newNode, oldNode)
|
||||||
|
if newNode.events.len != 0 or oldNode.events.len != 0:
|
||||||
|
mergeEvents(newNode, oldNode)
|
||||||
|
|
||||||
let newLength = newNode.len
|
let newLength = newNode.len
|
||||||
var oldLength = oldNode.len
|
var oldLength = oldNode.len
|
||||||
|
|
|
||||||
|
|
@ -483,6 +483,7 @@ proc clearTimeout*(t: Timeout) {.importc, nodecl.}
|
||||||
|
|
||||||
# EventTarget "methods"
|
# EventTarget "methods"
|
||||||
proc addEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), useCapture: bool = false)
|
proc addEventListener*(et: EventTarget, ev: cstring, cb: proc(ev: Event), useCapture: bool = false)
|
||||||
|
proc removeEventListener*(et: EventTarget; ev: cstring; cb: proc(ev: Event))
|
||||||
|
|
||||||
# Window "methods"
|
# Window "methods"
|
||||||
proc alert*(w: Window, msg: cstring)
|
proc alert*(w: Window, msg: cstring)
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ buildLookupTables()
|
||||||
|
|
||||||
type
|
type
|
||||||
EventHandler* = proc (ev: Event; target: VNode) {.closure.}
|
EventHandler* = proc (ev: Event; target: VNode) {.closure.}
|
||||||
|
NativeEventHandler* = proc (ev: Event) {.closure.}
|
||||||
VKey* = int
|
VKey* = int
|
||||||
|
|
||||||
VNode* = ref object of RootObj
|
VNode* = ref object of RootObj
|
||||||
|
|
@ -113,7 +114,7 @@ type
|
||||||
kids: seq[VNode]
|
kids: seq[VNode]
|
||||||
# even index: key, odd index: value; done this way for memory efficiency:
|
# even index: key, odd index: value; done this way for memory efficiency:
|
||||||
attrs: seq[cstring]
|
attrs: seq[cstring]
|
||||||
events*: seq[(EventKind, EventHandler)]
|
events*: seq[(EventKind, EventHandler, NativeEventHandler)]
|
||||||
when false:
|
when false:
|
||||||
hash*: Hash
|
hash*: Hash
|
||||||
validHash*: bool
|
validHash*: bool
|
||||||
|
|
@ -222,7 +223,7 @@ proc sameAttrs*(a, b: VNode): bool =
|
||||||
if a.attrs[i] != b.attrs[i]: return false
|
if a.attrs[i] != b.attrs[i]: return false
|
||||||
|
|
||||||
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, nil))
|
||||||
|
|
||||||
template toStringAttr(field) =
|
template toStringAttr(field) =
|
||||||
if n.field != nil:
|
if n.field != nil:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue