From 6c152ed516b2154fc16b26248676be9aa5601533 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 10 Jul 2017 21:42:22 +0200 Subject: [PATCH] smart attribute comparisons --- src/karax.nim | 19 ++++++++++++++++--- src/vdom.nim | 3 +++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/karax.nim b/src/karax.nim index 13c52a2..2035f19 100644 --- a/src/karax.nim +++ b/src/karax.nim @@ -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.. 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: diff --git a/src/vdom.nim b/src/vdom.nim index 997b059..f751676 100644 --- a/src/vdom.nim +++ b/src/vdom.nim @@ -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