@@ -5,6 +5,10 @@ function isElseIf ( node ) {
55 return node && node . children . length === 1 && node . children [ 0 ] . type === 'IfBlock' ;
66}
77
8+ function isElseBranch ( branch ) {
9+ return branch . block && ! branch . condition ;
10+ }
11+
812function getBranches ( generator , block , state , node ) {
913 const branches = [ {
1014 condition : block . contextualise ( node . expression ) . snippet ,
@@ -48,18 +52,22 @@ export default function visitIfBlock ( generator, block, state, node ) {
4852 const anchor = node . needsAnchor ? block . getUniqueName ( `${ name } _anchor` ) : ( node . next && node . next . _state . name ) || 'null' ;
4953 const params = block . params . join ( ', ' ) ;
5054
51- const vars = { name, anchor, params } ;
52-
5355 if ( node . needsAnchor ) {
5456 block . addElement ( anchor , `${ generator . helper ( 'createComment' ) } ()` , state . parentNode , true ) ;
5557 } else if ( node . next ) {
5658 node . next . usedAsAnchor = true ;
5759 }
5860
5961 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+
6066 const dynamic = branches [ 0 ] . hasUpdateMethod ; // can use [0] as proxy for all, since they necessarily have the same value
6167 const hasOutros = branches [ 0 ] . hasOutroMethod ;
6268
69+ const vars = { name, anchor, params, if_name, hasElse } ;
70+
6371 if ( node . else ) {
6472 if ( hasOutros ) {
6573 compoundWithOutros ( generator , block , state , node , branches , dynamic , vars ) ;
@@ -71,7 +79,7 @@ export default function visitIfBlock ( generator, block, state, node ) {
7179 }
7280
7381 block . builders . destroy . addLine (
74- `if ( ${ name } ) ${ name } .destroy( ${ state . parentNode ? 'false' : 'detach' } );`
82+ `${ if_name } ${ name } .destroy( ${ state . parentNode ? 'false' : 'detach' } );`
7583 ) ;
7684}
7785
@@ -145,9 +153,10 @@ function simple ( generator, block, state, node, branch, dynamic, { name, anchor
145153 ` ) ;
146154}
147155
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 } ) {
149157 const get_block = block . getUniqueName ( `get_block` ) ;
150158 const current_block = block . getUniqueName ( `current_block` ) ;
159+ const current_block_and = hasElse ? '' : `${ current_block } && ` ;
151160
152161 block . builders . create . addBlock ( deindent `
153162 function ${ get_block } ( ${ params } ) {
@@ -157,24 +166,24 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
157166 }
158167
159168 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 } );
161170 ` ) ;
162171
163172 const isToplevel = ! state . parentNode ;
164173 const mountOrIntro = branches [ 0 ] . hasIntroMethod ? 'intro' : 'mount' ;
165174
166175 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 );` ) ;
168177 } 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 );` ) ;
170179 }
171180
172181 const parentNode = state . parentNode || `${ anchor } .parentNode` ;
173182
174183 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 } );
178187 ` ;
179188
180189 if ( dynamic ) {
@@ -196,13 +205,15 @@ function compound ( generator, block, state, node, branches, dynamic, { name, an
196205
197206// if any of the siblings have outros, we need to keep references to the blocks
198207// (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 } ) {
200209 const get_block = block . getUniqueName ( `get_block` ) ;
201210 const current_block_index = block . getUniqueName ( `current_block_index` ) ;
202211 const previous_block_index = block . getUniqueName ( `previous_block_index` ) ;
203212 const if_block_creators = block . getUniqueName ( `if_block_creators` ) ;
204213 const if_blocks = block . getUniqueName ( `if_blocks` ) ;
205214
215+ const if_current_block_index = hasElse ? '' : `if ( ~${ current_block_index } ) ` ;
216+
206217 block . addVariable ( current_block_index ) ;
207218
208219 block . builders . create . addBlock ( deindent `
@@ -217,18 +228,27 @@ function compoundWithOutros ( generator, block, state, node, branches, dynamic,
217228 return `${ condition ? `if ( ${ condition } ) ` : '' } return ${ block ? i : - 1 } ;` ;
218229 } ) . join ( '\n' ) }
219230 }
231+ ` ) ;
220232
221- if ( ~( ${ current_block_index } = ${ get_block } ( ${ params } ) ) ) {
233+ if ( hasElse ) {
234+ block . builders . create . addBlock ( deindent `
235+ ${ current_block_index } = ${ get_block } ( ${ params } );
222236 ${ 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+ }
225245
226246 const isToplevel = ! state . parentNode ;
227247 const mountOrIntro = branches [ 0 ] . hasIntroMethod ? 'intro' : 'mount' ;
228248 const initialTarget = isToplevel ? block . target : state . parentNode ;
229249
230250 ( 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 );`
232252 ) ;
233253
234254 const parentNode = state . parentNode || `${ anchor } .parentNode` ;
@@ -241,23 +261,36 @@ function compoundWithOutros ( generator, block, state, node, branches, dynamic,
241261 ${ if_blocks } [ ${ previous_block_index } ] = null;
242262 });
243263 }
264+ ` ;
244265
245- if ( ~${ current_block_index } ) {
266+ if ( hasElse ) {
267+ block . builders . create . addBlock ( deindent `
246268 ${ name } = ${ if_blocks } [ ${ current_block_index } ];
247269 if ( !${ name } ) {
248270 ${ name } = ${ if_blocks } [ ${ current_block_index } ] = ${ if_block_creators } [ ${ current_block_index } ]( ${ params } , ${ block . component } );
249271 }
250272
251273 ${ 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+ }
254287
255288 if ( dynamic ) {
256289 block . builders . update . addBlock ( deindent `
257290 var ${ previous_block_index } = ${ current_block_index } ;
258291 ${ current_block_index } = ${ get_block } ( state );
259292 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 } );
261294 } else {
262295 ${ changeBlock }
263296 }
0 commit comments