diff algorithm also diffs components' expansions
This commit is contained in:
parent
994a51a1f0
commit
c8030bc185
2 changed files with 22 additions and 7 deletions
|
|
@ -177,8 +177,7 @@ proc eq(a, b: VNode; deep: bool): EqResult =
|
||||||
result = similar
|
result = similar
|
||||||
if not sameAttrs(a, b): return different
|
if not sameAttrs(a, b): return different
|
||||||
if a.class != b.class: return different
|
if a.class != b.class: return different
|
||||||
# XXX Fixme: smart diffing still is broken for complex apps:
|
if a.style != b.style: return similar
|
||||||
if a.style != b.style: return different # similar
|
|
||||||
# Do not test event listeners here!
|
# Do not test event listeners here!
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
@ -206,7 +205,10 @@ proc updateStyles(newNode, oldNode: VNode; deep: bool) =
|
||||||
else: oldNode.dom.style = Style()
|
else: oldNode.dom.style = Style()
|
||||||
oldNode.style = newNode.style
|
oldNode.style = newNode.style
|
||||||
if deep:
|
if deep:
|
||||||
assert newNode.len == oldNode.len
|
if newNode.len != oldNode.len:
|
||||||
|
kout cstring"argh ", newNode.len, " ", oldNode.len
|
||||||
|
kout newNode, oldNode
|
||||||
|
doAssert newNode.len == oldNode.len
|
||||||
for i in 0 ..< newNode.len:
|
for i in 0 ..< newNode.len:
|
||||||
updateStyles(newNode[i], oldNode[i], deep)
|
updateStyles(newNode[i], oldNode[i], deep)
|
||||||
|
|
||||||
|
|
@ -224,8 +226,18 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode;
|
||||||
if res == changed:
|
if res == changed:
|
||||||
assert oldNode.kind == VNodeKind.component
|
assert oldNode.kind == VNodeKind.component
|
||||||
let x = VComponent(oldNode)
|
let x = VComponent(oldNode)
|
||||||
n = vnodeToDom(x.renderImpl(x), kxi)
|
let oldExpanded = x.expanded
|
||||||
|
x.expanded = x.renderImpl(x)
|
||||||
x.updatedImpl(x)
|
x.updatedImpl(x)
|
||||||
|
if oldExpanded == nil:
|
||||||
|
n = vnodeToDom(x.expanded, kxi)
|
||||||
|
else:
|
||||||
|
if updateElement(parent, current, x.expanded, oldExpanded, kxi):
|
||||||
|
n = x.expanded.dom
|
||||||
|
doAssert n != nil, "expanded.dom is nil"
|
||||||
|
else:
|
||||||
|
n = oldExpanded.dom
|
||||||
|
doAssert n != nil, "old expanded.dom is nil"
|
||||||
result = true
|
result = true
|
||||||
else:
|
else:
|
||||||
detach(oldNode)
|
detach(oldNode)
|
||||||
|
|
@ -234,10 +246,10 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode;
|
||||||
replaceById(kxi.rootId, n)
|
replaceById(kxi.rootId, n)
|
||||||
else:
|
else:
|
||||||
parent.replaceChild(n, current)
|
parent.replaceChild(n, current)
|
||||||
|
elif res == similar:
|
||||||
|
updateStyles(newNode, oldNode, false)
|
||||||
else:
|
else:
|
||||||
if res == similar: updateStyles(newNode, oldNode, false)
|
|
||||||
newNode.dom = oldNode.dom
|
newNode.dom = oldNode.dom
|
||||||
|
|
||||||
if newNode.kind != VNodeKind.text:
|
if newNode.kind != VNodeKind.text:
|
||||||
let newLength = newNode.len
|
let newLength = newNode.len
|
||||||
var oldLength = oldNode.len
|
var oldLength = oldNode.len
|
||||||
|
|
@ -266,8 +278,8 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode;
|
||||||
of different, changed: break
|
of different, changed: break
|
||||||
of similar:
|
of similar:
|
||||||
#updateDom(a, b)
|
#updateDom(a, b)
|
||||||
|
updateStyles(a[i], b, true)
|
||||||
a[i] = b
|
a[i] = b
|
||||||
#updateStyles(a, b, true)
|
|
||||||
action
|
action
|
||||||
|
|
||||||
while commonPrefix < minLength:
|
while commonPrefix < minLength:
|
||||||
|
|
@ -299,6 +311,7 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode;
|
||||||
|
|
||||||
for i in pos..oldPos:
|
for i in pos..oldPos:
|
||||||
detach(oldNode[i])
|
detach(oldNode[i])
|
||||||
|
doAssert pos < current.childNodes.len
|
||||||
current.removeChild(current.childNodes[pos])
|
current.removeChild(current.childNodes[pos])
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,8 @@ type
|
||||||
## should call 'markDirty' instead which is an alias for
|
## should call 'markDirty' instead which is an alias for
|
||||||
## 'inc version'.
|
## 'inc version'.
|
||||||
renderedVersion*: int ## Do not touch. Used by karax.
|
renderedVersion*: int ## Do not touch. Used by karax.
|
||||||
|
expanded*: VNode ## Do not touch. Used by karax. The VDOM the component
|
||||||
|
## expanded to.
|
||||||
|
|
||||||
proc value*(n: VNode): cstring = n.text
|
proc value*(n: VNode): cstring = n.text
|
||||||
proc `value=`*(n: VNode; v: cstring) = n.text = v
|
proc `value=`*(n: VNode; v: cstring) = n.text = v
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue