Avoid using node.childNodes
This commit is contained in:
parent
d3e1d28c89
commit
4c582d7c06
2 changed files with 48 additions and 28 deletions
|
|
@ -164,7 +164,13 @@ proc updateDirtyElements(parent, current: Node, newNode: VNode) =
|
||||||
# leave early if we know there cannot be anything left to do:
|
# leave early if we know there cannot be anything left to do:
|
||||||
#if dirtyCount <= 0: return
|
#if dirtyCount <= 0: return
|
||||||
|
|
||||||
|
proc setDomField(a, b: VNode) =
|
||||||
|
a.dom = b.dom
|
||||||
|
for i in 0..<len(a):
|
||||||
|
setDomField(a[i], b[i])
|
||||||
|
|
||||||
proc updateElement(parent, current: Node, newNode, oldNode: VNode) =
|
proc updateElement(parent, current: Node, newNode, oldNode: VNode) =
|
||||||
|
newNode.dom = oldNode.dom
|
||||||
if not equalsShallow(newNode, oldNode):
|
if not equalsShallow(newNode, oldNode):
|
||||||
detach(oldNode)
|
detach(oldNode)
|
||||||
let n = vnodeToDom(newNode)
|
let n = vnodeToDom(newNode)
|
||||||
|
|
@ -175,7 +181,6 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode) =
|
||||||
elif newNode.kind != VNodeKind.text:
|
elif newNode.kind != VNodeKind.text:
|
||||||
let newLength = newNode.len
|
let newLength = newNode.len
|
||||||
var oldLength = oldNode.len
|
var oldLength = oldNode.len
|
||||||
let minLength = min(newLength, oldLength)
|
|
||||||
assert oldNode.kind == newNode.kind
|
assert oldNode.kind == newNode.kind
|
||||||
when defined(simpleDiff):
|
when defined(simpleDiff):
|
||||||
for i in 0..min(newLength, oldLength)-1:
|
for i in 0..min(newLength, oldLength)-1:
|
||||||
|
|
@ -188,36 +193,50 @@ proc updateElement(parent, current: Node, newNode, oldNode: VNode) =
|
||||||
detach(oldNode[i])
|
detach(oldNode[i])
|
||||||
current.removeChild(current.lastChild)
|
current.removeChild(current.lastChild)
|
||||||
else:
|
else:
|
||||||
var commonPrefix = 0
|
var left = 0
|
||||||
while commonPrefix < minLength and
|
var rightNew = newLength - 1
|
||||||
equalsTree(newNode[commonPrefix], oldNode[commonPrefix]):
|
var rightOld = oldLength - 1
|
||||||
inc commonPrefix
|
|
||||||
|
|
||||||
var oldPos = oldLength - 1
|
while left <= min(rightNew, rightOld):
|
||||||
var newPos = newLength - 1
|
var minRight = min(rightOld, rightNew)
|
||||||
while oldPos >= commonPrefix and newPos >= commonPrefix and
|
|
||||||
equalsTree(newNode[newPos], oldNode[oldPos]):
|
|
||||||
dec oldPos
|
|
||||||
dec newPos
|
|
||||||
|
|
||||||
var pos = min(oldPos, newPos) + 1
|
while left <= minRight and
|
||||||
for i in commonPrefix..pos-1:
|
equalsTree(newNode[left], oldNode[left]):
|
||||||
updateElement(current, current.childNodes[i], newNode[i], oldNode[i])
|
#newNode[left] = oldNode[left]
|
||||||
|
setDomField(newNode[left], oldNode[left])
|
||||||
|
inc left
|
||||||
|
|
||||||
var nextChildPos = oldPos + 1
|
while rightOld > left and rightNew > left and
|
||||||
while pos <= newPos:
|
equalsTree(newNode[rightNew], oldNode[rightOld]):
|
||||||
|
#newNode[rightNew].dom = oldNode[rightOld].dom
|
||||||
|
setDomField(newNode[rightNew], oldNode[rightOld])
|
||||||
|
dec rightOld
|
||||||
|
dec rightNew
|
||||||
|
|
||||||
|
minRight = min(rightOld, rightNew)
|
||||||
|
if left <= minRight:
|
||||||
|
updateElement(current, oldNode[left].dom, newNode[left], oldNode[left])
|
||||||
|
inc left
|
||||||
|
|
||||||
|
if left < minRight:
|
||||||
|
updateElement(current, oldNode[rightOld].dom, newNode[rightNew], oldNode[rightOld])
|
||||||
|
dec rightNew
|
||||||
|
dec rightOld
|
||||||
|
|
||||||
|
var nextChildPos = rightOld + 1
|
||||||
|
while left <= rightNew:
|
||||||
if nextChildPos == oldLength:
|
if nextChildPos == oldLength:
|
||||||
current.appendChild(vnodeToDom(newNode[pos]))
|
current.appendChild(vnodeToDom(newNode[left]))
|
||||||
else:
|
else:
|
||||||
current.insertBefore(vnodeToDom(newNode[pos]), current.childNodes[nextChildPos])
|
current.insertBefore(vnodeToDom(newNode[left]), oldNode[rightOld + 1].dom)
|
||||||
# added new Node, so old state of VDOM have one more Node
|
# added new Node, so old state of VDOM have one more Node
|
||||||
inc oldLength
|
inc oldLength
|
||||||
inc pos
|
inc left
|
||||||
inc nextChildPos
|
inc nextChildPos
|
||||||
|
|
||||||
for i in pos..oldPos:
|
for i in left..rightOld:
|
||||||
|
current.removeChild(oldNode[i].dom)
|
||||||
detach(oldNode[i])
|
detach(oldNode[i])
|
||||||
current.removeChild(current.childNodes[pos])
|
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
var drawTimeout: Timeout
|
var drawTimeout: Timeout
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,7 @@ proc getAttr*(n: VNode; key: cstring): cstring =
|
||||||
|
|
||||||
proc len*(x: VNode): int = x.kids.len
|
proc len*(x: VNode): int = x.kids.len
|
||||||
proc `[]`*(x: VNode; idx: int): VNode = x.kids[idx]
|
proc `[]`*(x: VNode; idx: int): VNode = x.kids[idx]
|
||||||
|
proc `[]=`*(x: VNode; idx: int, y: VNode) = x.kids[idx] = y
|
||||||
proc add*(parent, kid: VNode) = parent.kids.add kid
|
proc add*(parent, kid: VNode) = parent.kids.add kid
|
||||||
proc newVNode*(kind: VNodeKind): VNode = VNode(kind: kind, key: -1)
|
proc newVNode*(kind: VNodeKind): VNode = VNode(kind: kind, key: -1)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue