@@ -9,16 +9,16 @@ import {
9
9
set_hydrating
10
10
} from '../hydration.js' ;
11
11
import { block , branch , pause_effect , resume_effect } from '../../reactivity/effects.js' ;
12
- import { HYDRATION_START_ELSE , UNINITIALIZED } from '../../../../constants.js' ;
12
+ import { HYDRATION_START , HYDRATION_START_ELSE , UNINITIALIZED } from '../../../../constants.js' ;
13
13
14
14
/**
15
15
* @param {TemplateNode } node
16
- * @param {(branch: (fn: (anchor: Node) => void, flag?: boolean) => void) => void } fn
17
- * @param {boolean } [elseif] True if this is an `{:else if ...}` block rather than an `{#if ...}`, as that affects which transitions are considered 'local'
16
+ * @param {(branch: (fn: (anchor: Node, elseif?: [number,number] ) => void, flag?: boolean) => void) => void } fn
17
+ * @param {[number,number] } [elseif]
18
18
* @returns {void }
19
19
*/
20
- export function if_block ( node , fn , elseif = false ) {
21
- if ( hydrating ) {
20
+ export function if_block ( node , fn , [ root_index , hydrate_index ] = [ 0 , 0 ] ) {
21
+ if ( hydrating && root_index === 0 ) {
22
22
hydrate_next ( ) ;
23
23
}
24
24
@@ -33,26 +33,44 @@ export function if_block(node, fn, elseif = false) {
33
33
/** @type {UNINITIALIZED | boolean | null } */
34
34
var condition = UNINITIALIZED ;
35
35
36
- var flags = elseif ? EFFECT_TRANSPARENT : 0 ;
36
+ var flags = root_index > 0 ? EFFECT_TRANSPARENT : 0 ;
37
37
38
38
var has_branch = false ;
39
39
40
- const set_branch = ( /** @type {(anchor: Node) => void } */ fn , flag = true ) => {
40
+ const set_branch = (
41
+ /** @type {(anchor: Node, elseif?: [number,number]) => void } */ fn ,
42
+ flag = true
43
+ ) => {
41
44
has_branch = true ;
42
45
update_branch ( flag , fn ) ;
43
46
} ;
44
47
45
48
const update_branch = (
46
49
/** @type {boolean | null } */ new_condition ,
47
- /** @type {null | ((anchor: Node) => void) } */ fn
50
+ /** @type {null | ((anchor: Node, elseif?: [number,number] ) => void) } */ fn
48
51
) => {
49
52
if ( condition === ( condition = new_condition ) ) return ;
50
53
51
54
/** Whether or not there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */
52
55
let mismatch = false ;
53
56
54
- if ( hydrating ) {
55
- const is_else = /** @type {Comment } */ ( anchor ) . data === HYDRATION_START_ELSE ;
57
+ if ( hydrating && hydrate_index !== - 1 ) {
58
+ if ( root_index === 0 ) {
59
+ const data = /** @type {Comment } */ ( anchor ) . data ;
60
+ if ( data === HYDRATION_START ) {
61
+ hydrate_index = 0 ;
62
+ } else if ( data === HYDRATION_START_ELSE ) {
63
+ hydrate_index = Infinity ;
64
+ } else {
65
+ hydrate_index = parseInt ( data . substring ( 1 ) ) ;
66
+ if ( hydrate_index !== hydrate_index ) {
67
+ // if hydrate_index is NaN
68
+ // we set an invalid index to force mismatch
69
+ hydrate_index = condition ? Infinity : - 1 ;
70
+ }
71
+ }
72
+ }
73
+ const is_else = hydrate_index > root_index ;
56
74
57
75
if ( ! ! condition === is_else ) {
58
76
// Hydration mismatch: remove everything inside the anchor and start fresh.
@@ -62,6 +80,7 @@ export function if_block(node, fn, elseif = false) {
62
80
set_hydrate_node ( anchor ) ;
63
81
set_hydrating ( false ) ;
64
82
mismatch = true ;
83
+ hydrate_index = - 1 ; // ignore hydration in next else if
65
84
}
66
85
}
67
86
@@ -81,7 +100,7 @@ export function if_block(node, fn, elseif = false) {
81
100
if ( alternate_effect ) {
82
101
resume_effect ( alternate_effect ) ;
83
102
} else if ( fn ) {
84
- alternate_effect = branch ( ( ) => fn ( anchor ) ) ;
103
+ alternate_effect = branch ( ( ) => fn ( anchor , [ root_index + 1 , hydrate_index ] ) ) ;
85
104
}
86
105
87
106
if ( consequent_effect ) {
0 commit comments