teardownVNode
} = options
- function insertOrAppend(
+ function queueInsertOrAppend(
container: RenderNode,
newNode: RenderNode,
refNode: RenderNode | null
) {
const { flags, tag, data, children, childFlags, ref } = vnode
isSVG = isSVG || (flags & VNodeFlags.ELEMENT_SVG) > 0
+ // element creation is not deferred since it doesn't produce
+ // user-affecting side effects until inserted into the DOM
const el = (vnode.el = platformCreateElement(tag as string, isSVG))
if (data != null) {
for (const key in data) {
- patchData(el, key, null, data[key], null, vnode, isSVG)
+ if (!reservedPropRE.test(key)) {
+ platformPatchData(
+ el,
+ key,
+ null,
+ data[key],
+ null,
+ vnode,
+ isSVG,
+ unmountChildren
+ )
+ }
}
if (data.vnodeBeforeMount) {
data.vnodeBeforeMount(vnode)
}
}
if (container != null) {
- insertOrAppend(container, el, endNode)
+ queueInsertOrAppend(container, el, endNode)
}
if (ref) {
queueEffect(() => {
) {
const el = (vnode.el = platformCreateText(vnode.children as string))
if (container != null) {
- insertOrAppend(container, el, endNode)
+ queueInsertOrAppend(container, el, endNode)
}
}
// patching ------------------------------------------------------------------
- function patchData(
+ function queuePatchData(
el: RenderNode | (() => RenderNode),
key: string,
prevValue: any,
nextVNode: VNode,
isSVG: boolean
) {
- if (reservedPropRE.test(key)) {
- return
+ if (!reservedPropRE.test(key)) {
+ queueNodeOp([
+ platformPatchData,
+ el,
+ key,
+ prevValue,
+ nextValue,
+ preVNode,
+ nextVNode,
+ isSVG,
+ unmountChildren
+ ])
}
- platformPatchData(
- typeof el === 'function' ? el() : el,
- key,
- prevValue,
- nextValue,
- preVNode,
- nextVNode,
- isSVG,
- unmountChildren
- )
}
function patch(
const prevValue = prevDataOrEmpty[key]
const nextValue = nextDataOrEmpty[key]
if (prevValue !== nextValue) {
- patchData(
+ queuePatchData(
el,
key,
prevValue,
for (const key in prevDataOrEmpty) {
const prevValue = prevDataOrEmpty[key]
if (prevValue != null && !nextDataOrEmpty.hasOwnProperty(key)) {
- patchData(el, key, prevValue, null, prevVNode, nextVNode, isSVG)
+ queuePatchData(
+ el,
+ key,
+ prevValue,
+ null,
+ prevVNode,
+ nextVNode,
+ isSVG
+ )
}
}
}
}
}
} else {
- insertOrAppend(container, vnode.el as RenderNode, refNode)
+ queueInsertOrAppend(container, vnode.el as RenderNode, refNode)
}
}
// A data structure that stores a deferred DOM operation.
// the first element is the function to call, and the rest of the array
-// stores up to 3 arguments.
+// stores up to 8 arguments.
type Op = [Function, ...any[]]
// A "job" stands for a unit of work that needs to be performed.
function applyOp(op: Op) {
const fn = op[0]
- fn(op[1], op[2], op[3])
+ // optimize for more common cases
+ // only patchData needs 8 arguments
+ if (op.length <= 3) {
+ fn(op[1], op[2], op[3])
+ } else {
+ fn(op[1], op[2], op[3], op[4], op[5], op[6], op[7], op[8])
+ }
}