@@ -7,75 +7,62 @@ const DATA_KEY_ATTRIBUTE = "data-key"
77 * @param {VirtualNode } template - new virtual node tree.
88 * @param {VirtualNode } vNode - existing virtual node tree.
99 */
10- export const updateChildren = ( template , vNode , update ) => {
10+ export function patchChildren ( template , vNode , patch ) {
1111 const templateChildrenLength = template . children . length
1212 const vNodeChildrenLength = vNode . children . length
1313
1414 if ( ! templateChildrenLength && ! vNodeChildrenLength ) return
1515
1616 const vNodeKeyMap = createKeyMap ( vNode . children )
17+ let nextChildren = Array ( templateChildrenLength )
1718
18- // There were no keys found:
19+ if ( vNodeKeyMap !== undefined ) {
20+ forEach ( template . children , ( templateChild , idx ) => {
21+ const childNodes = vNode . node . childNodes
22+ const key = templateChild . attributes [ DATA_KEY_ATTRIBUTE ]
1923
20- if ( ! vNodeKeyMap ) {
21- // Remove extra nodes if template.children is smaller
22- let delta = vNodeChildrenLength - templateChildrenLength
23- if ( delta > 0 ) {
24- while ( delta -- > 0 ) {
25- const child = vNode . children . pop ( )
26- vNode . node . removeChild ( child . node )
27- }
28- }
24+ if ( Object . prototype . hasOwnProperty . call ( vNodeKeyMap , key ) ) {
25+ const keyedChild = vNodeKeyMap [ key ]
26+
27+ if ( Array . prototype . indexOf . call ( childNodes , keyedChild . node ) !== idx ) {
28+ insertBefore ( vNode , keyedChild , childNodes [ idx ] )
29+ }
30+
31+ nextChildren [ idx ] = keyedChild
2932
30- return forEach ( template . children , ( templateChild , idx ) => {
33+ // Remove entry to prevent dupes
34+ delete vNodeKeyMap [ key ]
35+ patch ( templateChild , nextChildren [ idx ] )
36+ } else {
37+ insertBefore ( vNode , templateChild , childNodes [ idx ] )
38+ nextChildren [ idx ] = templateChild
39+ }
40+ } )
41+ } else {
42+ forEach ( template . children , ( templateChild , idx ) => {
3143 const vNodeChild = vNode . children [ idx ]
3244
3345 if ( typeof vNodeChild !== "undefined" ) {
34- update ( templateChild , vNodeChild )
46+ patch ( templateChild , vNodeChild )
47+ nextChildren [ idx ] = vNodeChild
3548 } else {
3649 vNode . node . appendChild ( templateChild . node )
37- vNode . children . push ( templateChild )
50+ nextChildren [ idx ] = templateChild
3851 }
3952 } )
4053 }
4154
42- // There were keys found, resolve them:
43-
44- let nextChildren = Array ( templateChildrenLength )
45-
46- // Match keys and update/move children in-place
47- forEach ( template . children , ( child , idx ) => {
48- const childNodes = vNode . node . childNodes
49- const key = child . attributes [ DATA_KEY_ATTRIBUTE ]
50-
51- if ( Object . prototype . hasOwnProperty . call ( vNodeKeyMap , key ) ) {
52- const keyChild = vNodeKeyMap [ key ]
53-
54- if ( Array . prototype . indexOf . call ( childNodes , keyChild . node ) !== idx ) {
55- insertBefore ( vNode , keyChild , childNodes [ idx ] )
56- }
57-
58- nextChildren [ idx ] = keyChild
59-
60- // Prevent duplicates, remove the entry and let it insert at
61- // its natural index in the `else` block.
62- delete vNodeKeyMap [ key ]
63- update ( child , nextChildren [ idx ] )
64- } else {
65- insertBefore ( vNode , child , childNodes [ idx ] )
66- nextChildren [ idx ] = child
67- }
68- } )
69-
7055 vNode . children = nextChildren
7156
7257 // Remove any real nodes that are left over from the diff
7358 let childNodesLength = vNode . node . childNodes . length
7459 let delta = childNodesLength - templateChildrenLength
60+
7561 if ( delta > 0 ) {
76- while ( delta -- > 0 ) {
62+ while ( delta > 0 ) {
7763 vNode . node . removeChild ( vNode . node . childNodes [ childNodesLength - 1 ] )
7864 childNodesLength --
65+ delta --
7966 }
8067 }
8168}
0 commit comments