diff --git a/src/diff/children.js b/src/diff/children.js index d8b40170d1..a2d59c2f00 100644 --- a/src/diff/children.js +++ b/src/diff/children.js @@ -1,7 +1,6 @@ import { diff, unmount, applyRef } from './index'; import { createVNode, Fragment } from '../create-element'; import { EMPTY_OBJ, EMPTY_ARR } from '../constants'; -import { removeNode } from '../util'; import { getDomSibling } from '../component'; /** @@ -44,20 +43,6 @@ export function diffChildren( let oldChildrenLength = oldChildren.length; - // Only in very specific places should this logic be invoked (top level `render` and `diffElementNodes`). - // I'm using `EMPTY_OBJ` to signal when `diffChildren` is invoked in these situations. I can't use `null` - // for this purpose, because `null` is a valid value for `oldDom` which can mean to skip to this logic - // (e.g. if mounting a new tree in which the old DOM should be ignored (usually for Fragments). - if (oldDom == EMPTY_OBJ) { - if (excessDomChildren != null) { - oldDom = excessDomChildren[0]; - } else if (oldChildrenLength) { - oldDom = getDomSibling(oldParentVNode, 0); - } else { - oldDom = null; - } - } - newParentVNode._children = []; for (i = 0; i < renderResult.length; i++) { childVNode = renderResult[i]; @@ -185,7 +170,6 @@ export function diffChildren( childVNode, oldVNode, oldChildren, - excessDomChildren, newDom, oldDom ); @@ -228,13 +212,6 @@ export function diffChildren( newParentVNode._dom = firstChildDom; - // Remove children that are not part of any vnode. - if (excessDomChildren != null && typeof newParentVNode.type != 'function') { - for (i = excessDomChildren.length; i--; ) { - if (excessDomChildren[i] != null) removeNode(excessDomChildren[i]); - } - } - // Remove remaining oldChildren if there are any. for (i = oldChildrenLength; i--; ) { if (oldChildren[i] != null) { @@ -279,7 +256,6 @@ function reorderChildren(childVNode, oldDom, parentDom) { vnode, vnode, childVNode._children, - null, vnode._dom, oldDom ); @@ -314,7 +290,6 @@ function placeChild( childVNode, oldVNode, oldChildren, - excessDomChildren, newDom, oldDom ) { @@ -331,14 +306,10 @@ function placeChild( // can clean up the property childVNode._nextDom = undefined; } else if ( - excessDomChildren == oldVNode || + oldVNode == null || newDom != oldDom || newDom.parentNode == null ) { - // NOTE: excessDomChildren==oldVNode above: - // This is a compression of excessDomChildren==null && oldVNode==null! - // The values only have the same type when `null`. - outer: if (oldDom == null || oldDom.parentNode !== parentDom) { parentDom.appendChild(newDom); nextDom = null; diff --git a/src/diff/index.js b/src/diff/index.js index 46517aa3b9..c88f74553d 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -409,9 +409,16 @@ function diffElementNodes( newVNode.type === 'foreignObject' ? false : isSvg, excessDomChildren, commitQueue, - EMPTY_OBJ, + dom.firstChild, isHydrating ); + + // Remove children that are not part of any vnode. + if (excessDomChildren != null) { + for (i = excessDomChildren.length; i--; ) { + if (excessDomChildren[i] != null) removeNode(excessDomChildren[i]); + } + } } // (as above, don't diff props during hydration) diff --git a/src/render.js b/src/render.js index 101a81c83c..41e85b6f6b 100644 --- a/src/render.js +++ b/src/render.js @@ -47,11 +47,15 @@ export function render(vnode, parentDom, replaceNode) { ? [replaceNode] : oldVNode ? null - : parentDom.childNodes.length + : parentDom.firstChild ? EMPTY_ARR.slice.call(parentDom.childNodes) : null, commitQueue, - (!isHydrating && replaceNode) || EMPTY_OBJ, + !isHydrating && replaceNode + ? replaceNode + : oldVNode + ? oldVNode._dom + : parentDom.firstChild, isHydrating );