@@ -116,8 +116,7 @@ export interface RendererOptions<
116
116
parent : HostElement ,
117
117
anchor : HostNode | null ,
118
118
isSVG : boolean
119
- ) : HostElement
120
- setStaticContent ?( node : HostElement , content : string ) : void
119
+ ) : HostElement [ ]
121
120
}
122
121
123
122
// Renderer Node can technically be any object in the context of core renderer
@@ -333,8 +332,7 @@ function baseCreateRenderer(
333
332
nextSibling : hostNextSibling ,
334
333
setScopeId : hostSetScopeId = NOOP ,
335
334
cloneNode : hostCloneNode ,
336
- insertStaticContent : hostInsertStaticContent ,
337
- setStaticContent : hostSetStaticContent
335
+ insertStaticContent : hostInsertStaticContent
338
336
} = options
339
337
340
338
// Note: functions inside this closure should use `const xxx = () => {}`
@@ -373,11 +371,7 @@ function baseCreateRenderer(
373
371
if ( n1 == null ) {
374
372
mountStaticNode ( n2 , container , anchor , isSVG )
375
373
} else if ( __DEV__ ) {
376
- // static nodes are only patched during dev for HMR
377
- n2 . el = n1 . el
378
- if ( n2 . children !== n1 . children ) {
379
- hostSetStaticContent ! ( n2 . el ! , n2 . children as string )
380
- }
374
+ patchStaticNode ( n1 , n2 , container , isSVG )
381
375
}
382
376
break
383
377
case Fragment :
@@ -492,17 +486,83 @@ function baseCreateRenderer(
492
486
isSVG : boolean
493
487
) => {
494
488
if ( n2 . el && hostCloneNode !== undefined ) {
495
- hostInsert ( hostCloneNode ( n2 . el ) , container , anchor )
489
+ // static node was already mounted (and reused), or adopted
490
+ // server-rendered node during hydration (in this case its children can be
491
+ // stripped by SSR optimizations). Clone the dom nodes instead.
492
+ let cur : RendererElement | null = n2 . el
493
+ while ( cur && cur !== n2 . anchor ) {
494
+ hostInsert ( hostCloneNode ( cur ) , container , anchor )
495
+ cur = hostNextSibling ( cur )
496
+ }
497
+ hostInsert ( hostCloneNode ( n2 . anchor ! ) , container , anchor )
496
498
} else {
497
499
// static nodes are only present when used with compiler-dom/runtime-dom
498
500
// which guarantees presence of hostInsertStaticContent.
499
- n2 . el = hostInsertStaticContent ! (
501
+ ; [ n2 . el , n2 . anchor ] = hostInsertStaticContent ! (
502
+ n2 . children as string ,
503
+ container ,
504
+ anchor ,
505
+ isSVG
506
+ )
507
+ }
508
+ }
509
+
510
+ /**
511
+ * Dev / HMR only
512
+ */
513
+ const patchStaticNode = (
514
+ n1 : VNode ,
515
+ n2 : VNode ,
516
+ container : RendererElement ,
517
+ isSVG : boolean
518
+ ) => {
519
+ // static nodes are only patched during dev for HMR
520
+ if ( n2 . children !== n1 . children ) {
521
+ const anchor = hostNextSibling ( n1 . anchor ! )
522
+ // remove existing
523
+ removeStaticNode ( n1 )
524
+ // insert new
525
+ ; [ n2 . el , n2 . anchor ] = hostInsertStaticContent ! (
500
526
n2 . children as string ,
501
527
container ,
502
528
anchor ,
503
529
isSVG
504
530
)
531
+ } else {
532
+ n2 . el = n1 . el
533
+ n2 . anchor = n1 . anchor
534
+ }
535
+ }
536
+
537
+ /**
538
+ * Dev / HMR only
539
+ */
540
+ const moveStaticNode = (
541
+ vnode : VNode ,
542
+ container : RendererElement ,
543
+ anchor : RendererNode | null
544
+ ) => {
545
+ let cur = vnode . el
546
+ const end = vnode . anchor !
547
+ while ( cur && cur !== end ) {
548
+ const next = hostNextSibling ( cur )
549
+ hostInsert ( cur , container , anchor )
550
+ cur = next
551
+ }
552
+ hostInsert ( end , container , anchor )
553
+ }
554
+
555
+ /**
556
+ * Dev / HMR only
557
+ */
558
+ const removeStaticNode = ( vnode : VNode ) => {
559
+ let cur = vnode . el
560
+ while ( cur && cur !== vnode . anchor ) {
561
+ const next = hostNextSibling ( cur )
562
+ hostRemove ( cur )
563
+ cur = next
505
564
}
565
+ hostRemove ( vnode . anchor ! )
506
566
}
507
567
508
568
const processElement = (
@@ -1456,7 +1516,7 @@ function baseCreateRenderer(
1456
1516
n1 ,
1457
1517
n2 ,
1458
1518
container ,
1459
- parentAnchor ,
1519
+ null ,
1460
1520
parentComponent ,
1461
1521
parentSuspense ,
1462
1522
isSVG ,
@@ -1481,7 +1541,7 @@ function baseCreateRenderer(
1481
1541
n1 ,
1482
1542
n2 ,
1483
1543
container ,
1484
- parentAnchor ,
1544
+ null ,
1485
1545
parentComponent ,
1486
1546
parentSuspense ,
1487
1547
isSVG ,
@@ -1692,6 +1752,12 @@ function baseCreateRenderer(
1692
1752
return
1693
1753
}
1694
1754
1755
+ // static node move can only happen when force updating HMR
1756
+ if ( __DEV__ && type === Static ) {
1757
+ moveStaticNode ( vnode , container , anchor )
1758
+ return
1759
+ }
1760
+
1695
1761
// single nodes
1696
1762
const needTransition =
1697
1763
moveType !== MoveType . REORDER &&
@@ -1808,6 +1874,11 @@ function baseCreateRenderer(
1808
1874
return
1809
1875
}
1810
1876
1877
+ if ( __DEV__ && type === Static ) {
1878
+ removeStaticNode ( vnode )
1879
+ return
1880
+ }
1881
+
1811
1882
const performRemove = ( ) => {
1812
1883
hostRemove ( el ! )
1813
1884
if ( transition && ! transition . persisted && transition . afterLeave ) {
0 commit comments