@@ -5,6 +5,10 @@ function isElseIf ( node ) {
5
5
return node && node . children . length === 1 && node . children [ 0 ] . type === 'IfBlock' ;
6
6
}
7
7
8
+ function isElseBranch ( branch ) {
9
+ return branch . block && ! branch . condition ;
10
+ }
11
+
8
12
function getBranches ( generator , block , state , node ) {
9
13
const branches = [ {
10
14
condition : block . contextualise ( node . expression ) . snippet ,
@@ -48,18 +52,22 @@ export default function visitIfBlock ( generator, block, state, node ) {
48
52
const anchor = node . needsAnchor ? block . getUniqueName ( `${ name } _anchor` ) : ( node . next && node . next . _state . name ) || 'null' ;
49
53
const params = block . params . join ( ', ' ) ;
50
54
51
- const vars = { name, anchor, params } ;
52
-
53
55
if ( node . needsAnchor ) {
54
56
block . addElement ( anchor , `${ generator . helper ( 'createComment' ) } ()` , state . parentNode , true ) ;
55
57
} else if ( node . next ) {
56
58
node . next . usedAsAnchor = true ;
57
59
}
58
60
59
61
const branches = getBranches ( generator , block , state , node , generator . getUniqueName ( `create_if_block` ) ) ;
62
+
63
+ const hasElse = isElseBranch ( branches [ branches . length - 1 ] ) ;
64
+ const if_name = hasElse ? '' : `if ( ${ name } ) ` ;
65
+
60
66
const dynamic = branches [ 0 ] . hasUpdateMethod ; // can use [0] as proxy for all, since they necessarily have the same value
61
67
const hasOutros = branches [ 0 ] . hasOutroMethod ;
62
68
69
+ const vars = { name, anchor, params, if_name, hasElse } ;
70
+
63
71
if ( node . else ) {
64
72
if ( hasOutros ) {
65
73
compoundWithOutros ( generator , block , state , node , branches , dynamic , vars ) ;
@@ -71,7 +79,7 @@ export default function visitIfBlock ( generator, block, state, node ) {
71
79
}
72
80
73
81
block . builders . destroy . addLine (
74
- `if ( ${ name } ) ${ name } .destroy( ${ state . parentNode ? 'false' : 'detach' } );`
82
+ `${ if_name } ${ name } .destroy( ${ state . parentNode ? 'false' : 'detach' } );`
75
83
) ;
76
84
}
77
85
@@ -145,9 +153,10 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
145
153
` ) ;
146
154
}
147
155
148
- function compound ( generator , block , state , node , branches , dynamic , { name, anchor, params } ) {
156
+ function compound ( generator , block , state , node , branches , dynamic , { name, anchor, params, hasElse , if_name } ) {
149
157
const get_block = block . getUniqueName ( `get_block` ) ;
150
158
const current_block = block . getUniqueName ( `current_block` ) ;
159
+ const current_block_and = hasElse ? '' : `${ current_block } && ` ;
151
160
152
161
block . builders . create . addBlock ( deindent `
153
162
function ${ get_block } ( ${ params } ) {
@@ -157,24 +166,24 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
157
166
}
158
167
159
168
var ${ current_block } = ${ get_block } ( ${ params } );
160
- var ${ name } = ${ current_block } && ${ current_block } ( ${ params } , ${ block . component } );
169
+ var ${ name } = ${ current_block_and } ${ current_block } ( ${ params } , ${ block . component } );
161
170
` ) ;
162
171
163
172
const isToplevel = ! state . parentNode ;
164
173
const mountOrIntro = branches [ 0 ] . hasIntroMethod ? 'intro' : 'mount' ;
165
174
166
175
if ( isToplevel ) {
167
- block . builders . mount . addLine ( `if ( ${ name } ) ${ name } .${ mountOrIntro } ( ${ block . target } , null );` ) ;
176
+ block . builders . mount . addLine ( `${ if_name } ${ name } .${ mountOrIntro } ( ${ block . target } , null );` ) ;
168
177
} else {
169
- block . builders . create . addLine ( `if ( ${ name } ) ${ name } .${ mountOrIntro } ( ${ state . parentNode } , null );` ) ;
178
+ block . builders . create . addLine ( `${ if_name } ${ name } .${ mountOrIntro } ( ${ state . parentNode } , null );` ) ;
170
179
}
171
180
172
181
const parentNode = state . parentNode || `${ anchor } .parentNode` ;
173
182
174
183
const changeBlock = deindent `
175
- if ( ${ name } ) ${ name } .destroy( true );
176
- ${ name } = ${ current_block } && ${ current_block } ( ${ params } , ${ block . component } );
177
- if ( ${ name } ) ${ name } .${ mountOrIntro } ( ${ parentNode } , ${ anchor } );
184
+ ${ if_name } ${ name } .destroy( true );
185
+ ${ name } = ${ current_block_and } ${ current_block } ( ${ params } , ${ block . component } );
186
+ ${ if_name } ${ name } .${ mountOrIntro } ( ${ parentNode } , ${ anchor } );
178
187
` ;
179
188
180
189
if ( dynamic ) {
@@ -196,13 +205,15 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
196
205
197
206
// if any of the siblings have outros, we need to keep references to the blocks
198
207
// (TODO does this only apply to bidi transitions?)
199
- function compoundWithOutros ( generator , block , state , node , branches , dynamic , { name, anchor, params } ) {
208
+ function compoundWithOutros ( generator , block , state , node , branches , dynamic , { name, anchor, params, hasElse } ) {
200
209
const get_block = block . getUniqueName ( `get_block` ) ;
201
210
const current_block_index = block . getUniqueName ( `current_block_index` ) ;
202
211
const previous_block_index = block . getUniqueName ( `previous_block_index` ) ;
203
212
const if_block_creators = block . getUniqueName ( `if_block_creators` ) ;
204
213
const if_blocks = block . getUniqueName ( `if_blocks` ) ;
205
214
215
+ const if_current_block_index = hasElse ? '' : `if ( ~${ current_block_index } ) ` ;
216
+
206
217
block . addVariable ( current_block_index ) ;
207
218
208
219
block . builders . create . addBlock ( deindent `
@@ -217,18 +228,27 @@ function compoundWithOutros ( generator, block, state, node, branches, dynamic,
217
228
return `${ condition ? `if ( ${ condition } ) ` : '' } return ${ block ? i : - 1 } ;` ;
218
229
} ) . join ( '\n' ) }
219
230
}
231
+ ` ) ;
220
232
221
- if ( ~( ${ current_block_index } = ${ get_block } ( ${ params } ) ) ) {
233
+ if ( hasElse ) {
234
+ block . builders . create . addBlock ( deindent `
235
+ ${ current_block_index } = ${ get_block } ( ${ params } );
222
236
${ if_blocks } [ ${ current_block_index } ] = ${ if_block_creators } [ ${ current_block_index } ]( ${ params } , ${ block . component } );
223
- }
224
- ` ) ;
237
+ ` ) ;
238
+ } else {
239
+ block . builders . create . addBlock ( deindent `
240
+ if ( ~( ${ current_block_index } = ${ get_block } ( ${ params } ) ) ) {
241
+ ${ if_blocks } [ ${ current_block_index } ] = ${ if_block_creators } [ ${ current_block_index } ]( ${ params } , ${ block . component } );
242
+ }
243
+ ` ) ;
244
+ }
225
245
226
246
const isToplevel = ! state . parentNode ;
227
247
const mountOrIntro = branches [ 0 ] . hasIntroMethod ? 'intro' : 'mount' ;
228
248
const initialTarget = isToplevel ? block . target : state . parentNode ;
229
249
230
250
( isToplevel ? block . builders . mount : block . builders . create ) . addBlock (
231
- `if ( ~ ${ current_block_index } ) ${ if_blocks } [ ${ current_block_index } ].${ mountOrIntro } ( ${ initialTarget } , null );`
251
+ `${ if_current_block_index } ${ if_blocks } [ ${ current_block_index } ].${ mountOrIntro } ( ${ initialTarget } , null );`
232
252
) ;
233
253
234
254
const parentNode = state . parentNode || `${ anchor } .parentNode` ;
@@ -241,23 +261,36 @@ function compoundWithOutros ( generator, block, state, node, branches, dynamic,
241
261
${ if_blocks } [ ${ previous_block_index } ] = null;
242
262
});
243
263
}
264
+ ` ;
244
265
245
- if ( ~${ current_block_index } ) {
266
+ if ( hasElse ) {
267
+ block . builders . create . addBlock ( deindent `
246
268
${ name } = ${ if_blocks } [ ${ current_block_index } ];
247
269
if ( !${ name } ) {
248
270
${ name } = ${ if_blocks } [ ${ current_block_index } ] = ${ if_block_creators } [ ${ current_block_index } ]( ${ params } , ${ block . component } );
249
271
}
250
272
251
273
${ name } .${ mountOrIntro } ( ${ parentNode } , ${ anchor } );
252
- }
253
- ` ;
274
+ ` ) ;
275
+ } else {
276
+ block . builders . create . addBlock ( deindent `
277
+ if ( ~${ current_block_index } ) {
278
+ ${ name } = ${ if_blocks } [ ${ current_block_index } ];
279
+ if ( !${ name } ) {
280
+ ${ name } = ${ if_blocks } [ ${ current_block_index } ] = ${ if_block_creators } [ ${ current_block_index } ]( ${ params } , ${ block . component } );
281
+ }
282
+
283
+ ${ name } .${ mountOrIntro } ( ${ parentNode } , ${ anchor } );
284
+ }
285
+ ` ) ;
286
+ }
254
287
255
288
if ( dynamic ) {
256
289
block . builders . update . addBlock ( deindent `
257
290
var ${ previous_block_index } = ${ current_block_index } ;
258
291
${ current_block_index } = ${ get_block } ( state );
259
292
if ( ${ current_block_index } === ${ previous_block_index } ) {
260
- if ( ~ ${ current_block_index } ) ${ if_blocks } [ ${ current_block_index } ].update( changed, ${ params } );
293
+ ${ if_current_block_index } ${ if_blocks } [ ${ current_block_index } ].update( changed, ${ params } );
261
294
} else {
262
295
${ changeBlock }
263
296
}
0 commit comments