refactor: move clone step into util function
This commit is contained in:
parent
1b40fa6c16
commit
85bcc2b87c
@ -125,7 +125,9 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
container: RenderNode | null,
|
container: RenderNode | null,
|
||||||
contextVNode: MountedVNode | null,
|
contextVNode: MountedVNode | null,
|
||||||
isSVG: boolean,
|
isSVG: boolean,
|
||||||
endNode: RenderNode | null
|
endNode: RenderNode | null,
|
||||||
|
ownerArray?: VNode[],
|
||||||
|
index?: number
|
||||||
) {
|
) {
|
||||||
const { flags } = vnode
|
const { flags } = vnode
|
||||||
if (flags & VNodeFlags.ELEMENT) {
|
if (flags & VNodeFlags.ELEMENT) {
|
||||||
@ -149,11 +151,8 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
endNode: RenderNode | null
|
endNode: RenderNode | null
|
||||||
) {
|
) {
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
let child = children[i]
|
const child = getNextVNode(children, i)
|
||||||
if (child.el) {
|
mount(child, container, contextVNode, isSVG, endNode)
|
||||||
children[i] = child = cloneVNode(child)
|
|
||||||
}
|
|
||||||
mount(children[i], container, contextVNode, isSVG, endNode)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,20 +878,14 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
let nextChild
|
let nextChild
|
||||||
let prevChild
|
let prevChild
|
||||||
for (i; i < commonLength; i++) {
|
for (i; i < commonLength; i++) {
|
||||||
nextChild = nextChildren[i]
|
nextChild = getNextVNode(nextChildren, i)
|
||||||
prevChild = prevChildren[i]
|
prevChild = prevChildren[i]
|
||||||
if (nextChild.el) {
|
|
||||||
nextChildren[i] = nextChild = cloneVNode(nextChild)
|
|
||||||
}
|
|
||||||
patch(prevChild, nextChild, container, contextVNode, isSVG)
|
patch(prevChild, nextChild, container, contextVNode, isSVG)
|
||||||
prevChildren[i] = nextChild as MountedVNode
|
prevChildren[i] = nextChild as MountedVNode
|
||||||
}
|
}
|
||||||
if (prevLength < nextLength) {
|
if (prevLength < nextLength) {
|
||||||
for (i = commonLength; i < nextLength; i++) {
|
for (i = commonLength; i < nextLength; i++) {
|
||||||
nextChild = nextChildren[i]
|
nextChild = getNextVNode(nextChildren, i)
|
||||||
if (nextChild.el) {
|
|
||||||
nextChildren[i] = nextChild = cloneVNode(nextChild)
|
|
||||||
}
|
|
||||||
mount(nextChild, container, contextVNode, isSVG, endNode)
|
mount(nextChild, container, contextVNode, isSVG, endNode)
|
||||||
}
|
}
|
||||||
} else if (prevLength > nextLength) {
|
} else if (prevLength > nextLength) {
|
||||||
@ -917,15 +910,12 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
let i
|
let i
|
||||||
let j = 0
|
let j = 0
|
||||||
let prevVNode = prevChildren[j]
|
let prevVNode = prevChildren[j]
|
||||||
let nextVNode = nextChildren[j]
|
let nextVNode = getNextVNode(nextChildren, j)
|
||||||
let nextPos
|
let nextPos
|
||||||
|
|
||||||
outer: {
|
outer: {
|
||||||
// Sync nodes with the same key at the beginning.
|
// Sync nodes with the same key at the beginning.
|
||||||
while (prevVNode.key === nextVNode.key) {
|
while (prevVNode.key === nextVNode.key) {
|
||||||
if (nextVNode.el) {
|
|
||||||
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
|
|
||||||
}
|
|
||||||
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
||||||
prevChildren[j] = nextVNode as MountedVNode
|
prevChildren[j] = nextVNode as MountedVNode
|
||||||
j++
|
j++
|
||||||
@ -933,17 +923,14 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
break outer
|
break outer
|
||||||
}
|
}
|
||||||
prevVNode = prevChildren[j]
|
prevVNode = prevChildren[j]
|
||||||
nextVNode = nextChildren[j]
|
nextVNode = getNextVNode(nextChildren, j)
|
||||||
}
|
}
|
||||||
|
|
||||||
prevVNode = prevChildren[prevEnd]
|
prevVNode = prevChildren[prevEnd]
|
||||||
nextVNode = nextChildren[nextEnd]
|
nextVNode = getNextVNode(nextChildren, nextEnd)
|
||||||
|
|
||||||
// Sync nodes with the same key at the end.
|
// Sync nodes with the same key at the end.
|
||||||
while (prevVNode.key === nextVNode.key) {
|
while (prevVNode.key === nextVNode.key) {
|
||||||
if (nextVNode.el) {
|
|
||||||
nextChildren[nextEnd] = nextVNode = cloneVNode(nextVNode)
|
|
||||||
}
|
|
||||||
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
||||||
prevChildren[prevEnd] = nextVNode as MountedVNode
|
prevChildren[prevEnd] = nextVNode as MountedVNode
|
||||||
prevEnd--
|
prevEnd--
|
||||||
@ -952,7 +939,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
break outer
|
break outer
|
||||||
}
|
}
|
||||||
prevVNode = prevChildren[prevEnd]
|
prevVNode = prevChildren[prevEnd]
|
||||||
nextVNode = nextChildren[nextEnd]
|
nextVNode = getNextVNode(nextChildren, nextEnd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,10 +949,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
const nextNode =
|
const nextNode =
|
||||||
nextPos < nextLength ? nextChildren[nextPos].el : endNode
|
nextPos < nextLength ? nextChildren[nextPos].el : endNode
|
||||||
while (j <= nextEnd) {
|
while (j <= nextEnd) {
|
||||||
nextVNode = nextChildren[j]
|
nextVNode = getNextVNode(nextChildren, j)
|
||||||
if (nextVNode.el) {
|
|
||||||
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
|
|
||||||
}
|
|
||||||
j++
|
j++
|
||||||
mount(nextVNode, container, contextVNode, isSVG, nextNode)
|
mount(nextVNode, container, contextVNode, isSVG, nextNode)
|
||||||
}
|
}
|
||||||
@ -995,7 +979,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
prevVNode = prevChildren[i]
|
prevVNode = prevChildren[i]
|
||||||
if (patched < nextLeft) {
|
if (patched < nextLeft) {
|
||||||
for (j = nextStart; j <= nextEnd; j++) {
|
for (j = nextStart; j <= nextEnd; j++) {
|
||||||
nextVNode = nextChildren[j]
|
nextVNode = getNextVNode(nextChildren, j)
|
||||||
if (prevVNode.key === nextVNode.key) {
|
if (prevVNode.key === nextVNode.key) {
|
||||||
sources[j - nextStart] = i + 1
|
sources[j - nextStart] = i + 1
|
||||||
if (canRemoveWholeContent) {
|
if (canRemoveWholeContent) {
|
||||||
@ -1009,9 +993,6 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
} else {
|
} else {
|
||||||
pos = j
|
pos = j
|
||||||
}
|
}
|
||||||
if (nextVNode.el) {
|
|
||||||
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
|
|
||||||
}
|
|
||||||
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
||||||
patched++
|
patched++
|
||||||
break
|
break
|
||||||
@ -1046,16 +1027,13 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
queueRemoveVNode(prevChildren[prevStart++], container)
|
queueRemoveVNode(prevChildren[prevStart++], container)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nextVNode = nextChildren[j]
|
nextVNode = getNextVNode(nextChildren, j)
|
||||||
sources[j - nextStart] = i + 1
|
sources[j - nextStart] = i + 1
|
||||||
if (pos > j) {
|
if (pos > j) {
|
||||||
moved = true
|
moved = true
|
||||||
} else {
|
} else {
|
||||||
pos = j
|
pos = j
|
||||||
}
|
}
|
||||||
if (nextVNode.el) {
|
|
||||||
nextChildren[j] = nextVNode = cloneVNode(nextVNode)
|
|
||||||
}
|
|
||||||
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
patch(prevVNode, nextVNode, container, contextVNode, isSVG)
|
||||||
patched++
|
patched++
|
||||||
} else if (!canRemoveWholeContent) {
|
} else if (!canRemoveWholeContent) {
|
||||||
@ -1083,10 +1061,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
for (i = nextLeft - 1; i >= 0; i--) {
|
for (i = nextLeft - 1; i >= 0; i--) {
|
||||||
if (sources[i] === 0) {
|
if (sources[i] === 0) {
|
||||||
pos = i + nextStart
|
pos = i + nextStart
|
||||||
nextVNode = nextChildren[pos]
|
nextVNode = getNextVNode(nextChildren, pos)
|
||||||
if (nextVNode.el) {
|
|
||||||
nextChildren[pos] = nextVNode = cloneVNode(nextVNode)
|
|
||||||
}
|
|
||||||
nextPos = pos + 1
|
nextPos = pos + 1
|
||||||
mount(
|
mount(
|
||||||
nextVNode,
|
nextVNode,
|
||||||
@ -1114,10 +1089,7 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
for (i = nextLeft - 1; i >= 0; i--) {
|
for (i = nextLeft - 1; i >= 0; i--) {
|
||||||
if (sources[i] === 0) {
|
if (sources[i] === 0) {
|
||||||
pos = i + nextStart
|
pos = i + nextStart
|
||||||
nextVNode = nextChildren[pos]
|
nextVNode = getNextVNode(nextChildren, pos)
|
||||||
if (nextVNode.el) {
|
|
||||||
nextChildren[pos] = nextVNode = cloneVNode(nextVNode)
|
|
||||||
}
|
|
||||||
nextPos = pos + 1
|
nextPos = pos + 1
|
||||||
mount(
|
mount(
|
||||||
nextVNode,
|
nextVNode,
|
||||||
@ -1589,8 +1561,17 @@ export function createRenderer(options: RendererOptions) {
|
|||||||
return { render }
|
return { render }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Utils -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
// retrieves a vnode from a children array, making sure to clone it if the
|
||||||
|
// vnode is already mounted.
|
||||||
|
function getNextVNode(ownerArray: VNode[], index: number): VNode {
|
||||||
|
const vnode = ownerArray[index]
|
||||||
|
return vnode.el === null ? vnode : (ownerArray[index] = cloneVNode(vnode))
|
||||||
|
}
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
|
||||||
export function lis(arr: number[]): number[] {
|
function lis(arr: number[]): number[] {
|
||||||
const p = arr.slice()
|
const p = arr.slice()
|
||||||
const result = [0]
|
const result = [0]
|
||||||
let i
|
let i
|
||||||
|
Loading…
Reference in New Issue
Block a user