@@ -85,19 +85,26 @@ export function createPatchFunction (backend) {
8585 }
8686
8787 let inPre = 0
88- function createElm ( vnode , insertedVnodeQueue , nested ) {
89- let i
88+ function createElm ( vnode , insertedVnodeQueue , parentElm , refElm , nested ) {
89+ let i , isReactivated
9090 const data = vnode . data
9191 vnode . isRootInsert = ! nested
9292 if ( isDef ( data ) ) {
93- if ( isDef ( i = data . hook ) && isDef ( i = i . init ) ) i ( vnode )
93+ if ( isDef ( i = data . hook ) && isDef ( i = i . init ) ) {
94+ isReactivated = i ( vnode , false /* hydrating */ , parentElm , refElm )
95+ }
9496 // after calling the init hook, if the vnode is a child component
9597 // it should've created a child instance and mounted it. the child
9698 // component also has set the placeholder vnode's elm.
9799 // in that case we can just return the element and be done.
98100 if ( isDef ( i = vnode . child ) ) {
99101 initComponent ( vnode , insertedVnodeQueue )
100- return vnode . elm
102+ if ( isReactivated ) {
103+ // unlike a newly created component,
104+ // a reactivated keep-alive component doesn't insert itself
105+ insert ( parentElm , vnode . child . $el , refElm )
106+ }
107+ return
101108 }
102109 }
103110 const children = vnode . children
@@ -125,25 +132,56 @@ export function createPatchFunction (backend) {
125132 ? nodeOps . createElementNS ( vnode . ns , tag )
126133 : nodeOps . createElement ( tag , vnode )
127134 setScope ( vnode )
128- createChildren ( vnode , children , insertedVnodeQueue )
129- if ( isDef ( data ) ) {
130- invokeCreateHooks ( vnode , insertedVnodeQueue )
135+
136+ /* istanbul ignore if */
137+ if ( __WEEX__ ) {
138+ // in Weex, the default insertion order is parent-first.
139+ // List items can be optimized to use children-first insertion
140+ // with append="tree".
141+ const appendAsTree = data && data . appendAsTree
142+ if ( ! appendAsTree ) {
143+ if ( isDef ( data ) ) {
144+ invokeCreateHooks ( vnode , insertedVnodeQueue )
145+ }
146+ insert ( parentElm , vnode . elm , refElm )
147+ }
148+ createChildren ( vnode , children , insertedVnodeQueue )
149+ if ( appendAsTree ) {
150+ if ( isDef ( data ) ) {
151+ invokeCreateHooks ( vnode , insertedVnodeQueue )
152+ }
153+ insert ( parentElm , vnode . elm , refElm )
154+ }
155+ } else {
156+ createChildren ( vnode , children , insertedVnodeQueue )
157+ if ( isDef ( data ) ) {
158+ invokeCreateHooks ( vnode , insertedVnodeQueue )
159+ }
160+ insert ( parentElm , vnode . elm , refElm )
131161 }
162+
132163 if ( process . env . NODE_ENV !== 'production' && data && data . pre ) {
133164 inPre --
134165 }
135166 } else if ( vnode . isComment ) {
136167 vnode . elm = nodeOps . createComment ( vnode . text )
168+ insert ( parentElm , vnode . elm , refElm )
137169 } else {
138170 vnode . elm = nodeOps . createTextNode ( vnode . text )
171+ insert ( parentElm , vnode . elm , refElm )
172+ }
173+ }
174+
175+ function insert ( parent , elm , ref ) {
176+ if ( parent ) {
177+ nodeOps . insertBefore ( parent , elm , ref )
139178 }
140- return vnode . elm
141179 }
142180
143181 function createChildren ( vnode , children , insertedVnodeQueue ) {
144182 if ( Array . isArray ( children ) ) {
145183 for ( let i = 0 ; i < children . length ; ++ i ) {
146- nodeOps . appendChild ( vnode . elm , createElm ( children [ i ] , insertedVnodeQueue , true ) )
184+ createElm ( children [ i ] , insertedVnodeQueue , vnode . elm , null , true )
147185 }
148186 } else if ( isPrimitive ( vnode . text ) ) {
149187 nodeOps . appendChild ( vnode . elm , nodeOps . createTextNode ( vnode . text ) )
@@ -200,9 +238,9 @@ export function createPatchFunction (backend) {
200238 }
201239 }
202240
203- function addVnodes ( parentElm , before , vnodes , startIdx , endIdx , insertedVnodeQueue ) {
241+ function addVnodes ( parentElm , refElm , vnodes , startIdx , endIdx , insertedVnodeQueue ) {
204242 for ( ; startIdx <= endIdx ; ++ startIdx ) {
205- nodeOps . insertBefore ( parentElm , createElm ( vnodes [ startIdx ] , insertedVnodeQueue ) , before )
243+ createElm ( vnodes [ startIdx ] , insertedVnodeQueue , parentElm , refElm )
206244 }
207245 }
208246
@@ -271,7 +309,7 @@ export function createPatchFunction (backend) {
271309 let newEndIdx = newCh . length - 1
272310 let newStartVnode = newCh [ 0 ]
273311 let newEndVnode = newCh [ newEndIdx ]
274- let oldKeyToIdx , idxInOld , elmToMove , before
312+ let oldKeyToIdx , idxInOld , elmToMove , refElm
275313
276314 // removeOnly is a special flag used only by <transition-group>
277315 // to ensure removed elements stay in correct relative positions
@@ -305,7 +343,7 @@ export function createPatchFunction (backend) {
305343 if ( isUndef ( oldKeyToIdx ) ) oldKeyToIdx = createKeyToOldIdx ( oldCh , oldStartIdx , oldEndIdx )
306344 idxInOld = isDef ( newStartVnode . key ) ? oldKeyToIdx [ newStartVnode . key ] : null
307345 if ( isUndef ( idxInOld ) ) { // New element
308- nodeOps . insertBefore ( parentElm , createElm ( newStartVnode , insertedVnodeQueue ) , oldStartVnode . elm )
346+ createElm ( newStartVnode , insertedVnodeQueue , parentElm , oldStartVnode . elm )
309347 newStartVnode = newCh [ ++ newStartIdx ]
310348 } else {
311349 elmToMove = oldCh [ idxInOld ]
@@ -318,7 +356,7 @@ export function createPatchFunction (backend) {
318356 }
319357 if ( elmToMove . tag !== newStartVnode . tag ) {
320358 // same key but different element. treat as new element
321- nodeOps . insertBefore ( parentElm , createElm ( newStartVnode , insertedVnodeQueue ) , oldStartVnode . elm )
359+ createElm ( newStartVnode , insertedVnodeQueue , parentElm , oldStartVnode . elm )
322360 newStartVnode = newCh [ ++ newStartIdx ]
323361 } else {
324362 patchVnode ( elmToMove , newStartVnode , insertedVnodeQueue )
@@ -330,8 +368,8 @@ export function createPatchFunction (backend) {
330368 }
331369 }
332370 if ( oldStartIdx > oldEndIdx ) {
333- before = isUndef ( newCh [ newEndIdx + 1 ] ) ? null : newCh [ newEndIdx + 1 ] . elm
334- addVnodes ( parentElm , before , newCh , newStartIdx , newEndIdx , insertedVnodeQueue )
371+ refElm = isUndef ( newCh [ newEndIdx + 1 ] ) ? null : newCh [ newEndIdx + 1 ] . elm
372+ addVnodes ( parentElm , refElm , newCh , newStartIdx , newEndIdx , insertedVnodeQueue )
335373 } else if ( newStartIdx > newEndIdx ) {
336374 removeVnodes ( parentElm , oldCh , oldStartIdx , oldEndIdx )
337375 }
@@ -462,7 +500,7 @@ export function createPatchFunction (backend) {
462500 }
463501 }
464502
465- return function patch ( oldVnode , vnode , hydrating , removeOnly ) {
503+ return function patch ( oldVnode , vnode , hydrating , removeOnly , parentElm , refElm ) {
466504 if ( ! vnode ) {
467505 if ( oldVnode ) invokeDestroyHook ( oldVnode )
468506 return
@@ -473,12 +511,13 @@ export function createPatchFunction (backend) {
473511 const insertedVnodeQueue = [ ]
474512
475513 if ( ! oldVnode ) {
476- // empty mount, create new root element
514+ // empty mount (likely as component) , create new root element
477515 isInitialPatch = true
478- createElm ( vnode , insertedVnodeQueue )
516+ createElm ( vnode , insertedVnodeQueue , parentElm , refElm )
479517 } else {
480518 const isRealElement = isDef ( oldVnode . nodeType )
481519 if ( ! isRealElement && sameVnode ( oldVnode , vnode ) ) {
520+ // patch existing root node
482521 patchVnode ( oldVnode , vnode , insertedVnodeQueue , removeOnly )
483522 } else {
484523 if ( isRealElement ) {
@@ -507,14 +546,15 @@ export function createPatchFunction (backend) {
507546 // create an empty node and replace it
508547 oldVnode = emptyNodeAt ( oldVnode )
509548 }
549+
550+ // replacing existing element
510551 elm = oldVnode . elm
511552 parent = nodeOps . parentNode ( elm )
553+ createElm ( vnode , insertedVnodeQueue , parent , nodeOps . nextSibling ( elm ) )
512554
513- createElm ( vnode , insertedVnodeQueue )
514-
515- // component root element replaced.
516- // update parent placeholder node element, recursively
517555 if ( vnode . parent ) {
556+ // component root element replaced.
557+ // update parent placeholder node element, recursively
518558 let ancestor = vnode . parent
519559 while ( ancestor ) {
520560 ancestor . elm = vnode . elm
@@ -528,7 +568,6 @@ export function createPatchFunction (backend) {
528568 }
529569
530570 if ( parent !== null ) {
531- nodeOps . insertBefore ( parent , vnode . elm , nodeOps . nextSibling ( elm ) )
532571 removeVnodes ( parent , [ oldVnode ] , 0 , 0 )
533572 } else if ( isDef ( oldVnode . tag ) ) {
534573 invokeDestroyHook ( oldVnode )
0 commit comments