@@ -163,9 +163,7 @@ object init {
163
163
}
164
164
case Some (children) =>
165
165
children.foreach { child =>
166
- if (child != null ) { // TODO: is this necessary
167
- api.appendChild(elm, createElm(child, insertedVNodeQueue))
168
- }
166
+ api.appendChild(elm, createElm(child, insertedVNodeQueue))
169
167
}
170
168
}
171
169
vnode.data.hook.map { hooks =>
@@ -175,18 +173,18 @@ object init {
175
173
176
174
case None =>
177
175
vnode.children match {
178
- case None => vnode.elm = Some (api.createTextNode(vnode.text.get))
176
+ case None =>
177
+ vnode.elm = Some (api.createTextNode(vnode.text.getOrElse(" " )))
179
178
case Some (children) =>
180
179
val elm = api.createDocumentFragment
181
180
vnode.elm = Some (elm)
182
181
cbs.create.foreach(hook => hook(emptyNode, vnode))
183
182
children.foreach { child =>
184
- if (child != null ) {
185
- api.appendChild(
186
- elm,
187
- createElm(child, insertedVNodeQueue)
188
- )
189
- }
183
+ api.appendChild(
184
+ elm,
185
+ createElm(child, insertedVNodeQueue)
186
+ )
187
+
190
188
}
191
189
}
192
190
@@ -207,9 +205,7 @@ object init {
207
205
var i = startIdx
208
206
while (i <= endIdx) {
209
207
val ch = vnodes(i)
210
- if (ch != null ) { // TODO: is this necessary?
211
- api.insertBefore(parentElm, createElm(ch, insertedVNodeQueue), before)
212
- }
208
+ api.insertBefore(parentElm, createElm(ch, insertedVNodeQueue), before)
213
209
i += 1
214
210
}
215
211
}
@@ -220,9 +216,7 @@ object init {
220
216
cbs.destroy.foreach(hook => hook(vnode))
221
217
vnode.children.foreach {
222
218
_.foreach { child =>
223
- if (child != null ) { // TODO: is this necessary?
224
- invokeDestroyHook(child)
225
- }
219
+ invokeDestroyHook(child)
226
220
}
227
221
}
228
222
}
@@ -238,78 +232,69 @@ object init {
238
232
var i = startIdx
239
233
while (i <= endIdx) {
240
234
val ch = vnodes(i)
241
- if (ch != null ) { // TODO: is this necessary?
242
- ch.sel match {
243
- case Some (_) =>
244
- invokeDestroyHook(ch)
245
- val listeners = cbs.remove.length + 1
246
- val rm = createRmCb(ch.elm.get, listeners)
247
- cbs.remove.foreach(hook => hook(ch, rm))
248
- ch.data.hook
249
- .flatMap(_.remove)
250
- .fold(rm()) { hook => hook(ch, rm); () }
251
- case None => // text node
252
- api.removeChild(parentElm, ch.elm.get)
253
-
254
- }
235
+ ch.sel match {
236
+ case Some (_) =>
237
+ invokeDestroyHook(ch)
238
+ val listeners = cbs.remove.length + 1
239
+ val rm = createRmCb(ch.elm.get, listeners)
240
+ cbs.remove.foreach(hook => hook(ch, rm))
241
+ ch.data.hook
242
+ .flatMap(_.remove)
243
+ .fold(rm()) { hook => hook(ch, rm); () }
244
+ case None => // text node
245
+ api.removeChild(parentElm, ch.elm.get)
255
246
}
256
247
i += 1
257
248
}
258
249
}
259
250
260
- def getOrNull (vnodes : Array [VNode ], idx : Int ): VNode = {
261
- if (idx >= 0 && idx < vnodes.length) {
262
- vnodes(idx)
263
- } else {
264
- null
265
- }
266
- }
267
-
268
251
def updateChildren (
269
252
parentElm : dom.Node ,
270
253
oldCh : Array [VNode ],
271
254
newCh : Array [VNode ],
272
255
insertedVnodeQueue : VNodeQueue
273
256
): Unit = {
274
257
258
+ assert(oldCh.nonEmpty)
259
+ assert(newCh.nonEmpty)
260
+
275
261
var oldStartIdx = 0
276
262
var newStartIdx = 0
277
263
var oldEndIdx = oldCh.length - 1
278
- var oldStartVnode = getOrNull( oldCh, 0 )
279
- var oldEndVnode = getOrNull( oldCh, oldEndIdx)
264
+ var oldStartVnode = oldCh( 0 )
265
+ var oldEndVnode = oldCh( oldEndIdx)
280
266
var newEndIdx = newCh.length - 1
281
- var newStartVnode = getOrNull( newCh, 0 )
282
- var newEndVnode = getOrNull( newCh, newEndIdx)
267
+ var newStartVnode = newCh( 0 )
268
+ var newEndVnode = newCh( newEndIdx)
283
269
284
270
var oldKeyToIdx : Map [String , Int ] = null
285
- var elmToMove : VNode = null
286
271
287
272
while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
288
273
if (oldStartVnode == null ) {
289
274
oldStartIdx += 1
290
- oldStartVnode =
291
- getOrNull(oldCh, oldStartIdx) // Vnode might have been moved left
275
+ // Vnode might have been moved left
276
+ if (oldStartIdx <= oldEndIdx)
277
+ oldStartVnode = oldCh(oldStartIdx)
292
278
} else if (oldEndVnode == null ) {
293
279
oldEndIdx -= 1
294
- oldEndVnode = getOrNull(oldCh, oldEndIdx)
295
- } else if (newStartVnode == null ) {
296
- newStartIdx += 1
297
- newStartVnode = getOrNull(newCh, newStartIdx)
298
- } else if (newEndVnode == null ) {
299
- newEndIdx -= 1
300
- newEndVnode = getOrNull(newCh, newEndIdx)
280
+ if (oldStartIdx <= oldEndIdx)
281
+ oldEndVnode = oldCh(oldEndIdx)
301
282
} else if (sameVnode(oldStartVnode, newStartVnode)) {
302
283
patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue)
303
284
oldStartIdx += 1
304
- oldStartVnode = getOrNull(oldCh, oldStartIdx)
285
+ if (oldStartIdx <= oldEndIdx)
286
+ oldStartVnode = oldCh(oldStartIdx)
305
287
newStartIdx += 1
306
- newStartVnode = getOrNull(newCh, newStartIdx)
288
+ if (newStartIdx <= newEndIdx)
289
+ newStartVnode = newCh(newStartIdx)
307
290
} else if (sameVnode(oldEndVnode, newEndVnode)) {
308
291
patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue)
309
292
oldEndIdx -= 1
310
- oldEndVnode = getOrNull(oldCh, oldEndIdx)
293
+ if (oldStartIdx <= oldEndIdx)
294
+ oldEndVnode = oldCh(oldEndIdx)
311
295
newEndIdx -= 1
312
- newEndVnode = getOrNull(newCh, newEndIdx)
296
+ if (newStartIdx <= newEndIdx)
297
+ newEndVnode = newCh(newEndIdx)
313
298
} else if (sameVnode(oldStartVnode, newEndVnode)) {
314
299
// Vnode moved right
315
300
patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue)
@@ -319,9 +304,11 @@ object init {
319
304
api.nextSibling(oldEndVnode.elm.get)
320
305
)
321
306
oldStartIdx += 1
322
- oldStartVnode = getOrNull(oldCh, oldStartIdx)
307
+ if (oldStartIdx <= oldEndIdx)
308
+ oldStartVnode = oldCh(oldStartIdx)
323
309
newEndIdx -= 1
324
- newEndVnode = newCh(newEndIdx)
310
+ if (newStartIdx <= newEndIdx)
311
+ newEndVnode = newCh(newEndIdx)
325
312
} else if (sameVnode(oldEndVnode, newStartVnode)) {
326
313
// Vnode moved left
327
314
patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue)
@@ -331,9 +318,11 @@ object init {
331
318
oldStartVnode.elm
332
319
)
333
320
oldEndIdx -= 1
334
- oldEndVnode = getOrNull(oldCh, oldEndIdx)
321
+ if (oldStartIdx <= oldEndIdx)
322
+ oldEndVnode = oldCh(oldEndIdx)
335
323
newStartIdx += 1
336
- newStartVnode = getOrNull(newCh, newStartIdx)
324
+ if (newStartIdx <= newEndIdx)
325
+ newStartVnode = newCh(newStartIdx)
337
326
} else {
338
327
if (oldKeyToIdx == null ) {
339
328
oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx)
@@ -350,7 +339,7 @@ object init {
350
339
oldStartVnode.elm
351
340
)
352
341
case Some (idxInOld) =>
353
- elmToMove = oldCh(idxInOld)
342
+ val elmToMove = oldCh(idxInOld)
354
343
if (elmToMove.sel != newStartVnode.sel) {
355
344
api.insertBefore(
356
345
parentElm,
@@ -359,7 +348,7 @@ object init {
359
348
)
360
349
} else {
361
350
patchVnode(elmToMove, newStartVnode, insertedVnodeQueue)
362
- oldCh(idxInOld) = null // undefined as any
351
+ oldCh(idxInOld) = null
363
352
api.insertBefore(
364
353
parentElm,
365
354
elmToMove.elm.get,
@@ -368,12 +357,15 @@ object init {
368
357
}
369
358
}
370
359
newStartIdx += 1
371
- newStartVnode = getOrNull(newCh, newStartIdx)
360
+ if (newStartIdx <= newEndIdx)
361
+ newStartVnode = newCh(newStartIdx)
372
362
}
373
363
}
374
364
375
365
if (newStartIdx <= newEndIdx) {
376
- val before = Option (getOrNull(newCh, newEndIdx + 1 )).flatMap(_.elm)
366
+ val before =
367
+ if (newCh.length > newEndIdx + 1 ) newCh(newEndIdx + 1 ).elm
368
+ else None
377
369
addVnodes(
378
370
parentElm,
379
371
before,
0 commit comments