smart attribute comparisons

This commit is contained in:
Andreas Rumpf 2017-07-10 21:42:22 +02:00
commit 6c152ed516
2 changed files with 19 additions and 3 deletions

View file

@ -210,9 +210,8 @@ proc eq(a, b: VNode): EqResult =
let x = VComponent(b)
assert x.changedImpl != nil
return if x.changedImpl(x, VComponent(a)): changed else: identical
if not sameAttrs(a, b): return different
if a.class != b.class: return different
if not eq(a.style, b.style): return similar
if not eq(a.style, b.style) or not sameAttrs(a, b): return similar
# Do not test event listeners here!
return result
@ -223,6 +222,16 @@ proc updateStyles(newNode, oldNode: VNode) =
else: oldNode.dom.style = Style()
oldNode.style = newNode.style
proc updateAttributes(newNode, oldNode: VNode) =
# we keep the oldNode, but take over the attributes from the new node:
if oldNode.dom != nil:
for k, _ in attrs(oldNode):
oldNode.dom.removeAttribute(k)
for k, v in attrs(newNode):
if v != nil:
oldNode.dom.setAttr(k, v)
takeOverAttr(newNode, oldNode)
proc mergeEvents(newNode, oldNode: VNode; kxi: KaraxInstance) =
let d = oldNode.dom
for i in 0..<oldNode.events.len:
@ -301,6 +310,8 @@ proc apply(kxi: KaraxInstance) =
assert p.newChild.dom != nil
kxi.patchLenV = 0
var outputted = false
proc diff(newNode, oldNode: VNode; parent, current: Node; kxi: KaraxInstance): EqResult =
when defined(stats):
if kxi.recursion > 100:
@ -314,7 +325,9 @@ proc diff(newNode, oldNode: VNode; parent, current: Node; kxi: KaraxInstance): E
case result
of identical, similar:
newNode.dom = oldNode.dom
if result == similar: updateStyles(newNode, oldNode)
if result == similar:
updateStyles(newNode, oldNode)
updateAttributes(newNode, oldNode)
if newNode.events.len != 0 or oldNode.events.len != 0:
mergeEvents(newNode, oldNode, kxi)
if oldNode.kind == VNodeKind.input or oldNode.kind == VNodeKind.textarea:

View file

@ -199,6 +199,9 @@ proc getAttr*(n: VNode; key: cstring): cstring =
for i in countup(0, n.attrs.len-2, 2):
if n.attrs[i] == key: return n.attrs[i+1]
proc takeOverAttr*(newNode, oldNode: VNode) =
oldNode.attrs = newNode.attrs
proc len*(x: VNode): int = x.kids.len
proc `[]`*(x: VNode; idx: int): VNode = x.kids[idx]
proc `[]=`*(x: VNode; idx: int; y: VNode) = x.kids[idx] = y