Skip to content

Commit aa70188

Browse files
committed
fix(runtime-core): remove prod-only hoisted clone behavior for manual DOM manipulation compat
fix #6727 fix #6739
1 parent c0d8db8 commit aa70188

File tree

1 file changed

+59
-71
lines changed

1 file changed

+59
-71
lines changed

Diff for: packages/runtime-core/src/renderer.ts

+59-71
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,6 @@ function baseCreateRenderer(
345345
parentNode: hostParentNode,
346346
nextSibling: hostNextSibling,
347347
setScopeId: hostSetScopeId = NOOP,
348-
cloneNode: hostCloneNode,
349348
insertStaticContent: hostInsertStaticContent
350349
} = options
351350

@@ -618,82 +617,71 @@ function baseCreateRenderer(
618617
) => {
619618
let el: RendererElement
620619
let vnodeHook: VNodeHook | undefined | null
621-
const { type, props, shapeFlag, transition, patchFlag, dirs } = vnode
622-
if (
623-
!__DEV__ &&
624-
vnode.el &&
625-
hostCloneNode !== undefined &&
626-
patchFlag === PatchFlags.HOISTED
627-
) {
628-
// If a vnode has non-null el, it means it's being reused.
629-
// Only static vnodes can be reused, so its mounted DOM nodes should be
630-
// exactly the same, and we can simply do a clone here.
631-
// only do this in production since cloned trees cannot be HMR updated.
632-
el = vnode.el = hostCloneNode(vnode.el)
633-
} else {
634-
el = vnode.el = hostCreateElement(
635-
vnode.type as string,
636-
isSVG,
637-
props && props.is,
638-
props
620+
const { type, props, shapeFlag, transition, dirs } = vnode
621+
622+
el = vnode.el = hostCreateElement(
623+
vnode.type as string,
624+
isSVG,
625+
props && props.is,
626+
props
627+
)
628+
629+
// mount children first, since some props may rely on child content
630+
// being already rendered, e.g. `<select value>`
631+
if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
632+
hostSetElementText(el, vnode.children as string)
633+
} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
634+
mountChildren(
635+
vnode.children as VNodeArrayChildren,
636+
el,
637+
null,
638+
parentComponent,
639+
parentSuspense,
640+
isSVG && type !== 'foreignObject',
641+
slotScopeIds,
642+
optimized
639643
)
644+
}
640645

641-
// mount children first, since some props may rely on child content
642-
// being already rendered, e.g. `<select value>`
643-
if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
644-
hostSetElementText(el, vnode.children as string)
645-
} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
646-
mountChildren(
647-
vnode.children as VNodeArrayChildren,
648-
el,
649-
null,
650-
parentComponent,
651-
parentSuspense,
652-
isSVG && type !== 'foreignObject',
653-
slotScopeIds,
654-
optimized
655-
)
646+
if (dirs) {
647+
invokeDirectiveHook(vnode, null, parentComponent, 'created')
648+
}
649+
// props
650+
if (props) {
651+
for (const key in props) {
652+
if (key !== 'value' && !isReservedProp(key)) {
653+
hostPatchProp(
654+
el,
655+
key,
656+
null,
657+
props[key],
658+
isSVG,
659+
vnode.children as VNode[],
660+
parentComponent,
661+
parentSuspense,
662+
unmountChildren
663+
)
664+
}
656665
}
657-
658-
if (dirs) {
659-
invokeDirectiveHook(vnode, null, parentComponent, 'created')
666+
/**
667+
* Special case for setting value on DOM elements:
668+
* - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
669+
* - it needs to be forced (#1471)
670+
* #2353 proposes adding another renderer option to configure this, but
671+
* the properties affects are so finite it is worth special casing it
672+
* here to reduce the complexity. (Special casing it also should not
673+
* affect non-DOM renderers)
674+
*/
675+
if ('value' in props) {
676+
hostPatchProp(el, 'value', null, props.value)
660677
}
661-
// props
662-
if (props) {
663-
for (const key in props) {
664-
if (key !== 'value' && !isReservedProp(key)) {
665-
hostPatchProp(
666-
el,
667-
key,
668-
null,
669-
props[key],
670-
isSVG,
671-
vnode.children as VNode[],
672-
parentComponent,
673-
parentSuspense,
674-
unmountChildren
675-
)
676-
}
677-
}
678-
/**
679-
* Special case for setting value on DOM elements:
680-
* - it can be order-sensitive (e.g. should be set *after* min/max, #2325, #4024)
681-
* - it needs to be forced (#1471)
682-
* #2353 proposes adding another renderer option to configure this, but
683-
* the properties affects are so finite it is worth special casing it
684-
* here to reduce the complexity. (Special casing it also should not
685-
* affect non-DOM renderers)
686-
*/
687-
if ('value' in props) {
688-
hostPatchProp(el, 'value', null, props.value)
689-
}
690-
if ((vnodeHook = props.onVnodeBeforeMount)) {
691-
invokeVNodeHook(vnodeHook, parentComponent, vnode)
692-
}
678+
if ((vnodeHook = props.onVnodeBeforeMount)) {
679+
invokeVNodeHook(vnodeHook, parentComponent, vnode)
693680
}
694-
// scopeId
695-
setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent)
696681
}
682+
// scopeId
683+
setScopeId(el, vnode, vnode.scopeId, slotScopeIds, parentComponent)
684+
697685
if (__DEV__ || __FEATURE_PROD_DEVTOOLS__) {
698686
Object.defineProperty(el, '__vnode', {
699687
value: vnode,

0 commit comments

Comments
 (0)