@@ -4,7 +4,7 @@ import { AnimationOptions } from '../animations/animation';
4
4
import { App } from '../components/app/app' ;
5
5
import { Config } from '../config/config' ;
6
6
import { convertToView , convertToViews , NavOptions , DIRECTION_BACK , DIRECTION_FORWARD , INIT_ZINDEX ,
7
- TransitionResolveFn , TransitionRejectFn , TransitionInstruction , ViewState } from './nav-util' ;
7
+ TransitionResolveFn , TransitionInstruction , ViewState } from './nav-util' ;
8
8
import { setZIndex } from './nav-util' ;
9
9
import { DeepLinker } from './deep-linker' ;
10
10
import { GestureController } from '../gestures/gesture-controller' ;
@@ -254,28 +254,40 @@ export class NavControllerBase extends Ion implements NavController {
254
254
255
255
// there is no transition happening right now
256
256
// get the next instruction
257
- const ti = this . _queue . shift ( ) ;
257
+ const ti = this . _nextTI ( ) ;
258
258
if ( ! ti ) {
259
- this . setTransitioning ( false ) ;
260
259
return false ;
261
260
}
262
261
263
- this . setTransitioning ( true , ACTIVE_TRANSITION_MAX_TIME ) ;
264
- const viewsLength = this . _views . length ;
265
- const activeView = this . getActive ( ) ;
262
+ // Get entering and leaving views
263
+ const leavingView = this . getActive ( ) ;
264
+ const enteringView = this . _getEnteringView ( ti , leavingView ) ;
266
265
267
- let enteringView : ViewController ;
268
- let leavingView : ViewController = activeView ;
269
- const destroyQueue : ViewController [ ] = [ ] ;
266
+ // Initialize enteringView
267
+ if ( enteringView && isBlank ( enteringView . _state ) ) {
268
+ // render the entering view, and all child navs and views
269
+ // ******** DOM WRITE ****************
270
+ this . _viewInit ( enteringView ) ;
271
+ }
270
272
271
- const opts = ti . opts || { } ;
272
- const resolve = ti . resolve ;
273
- const reject = ti . reject ;
274
- let insertViews = ti . insertViews ;
275
- ti . resolve = ti . reject = ti . opts = ti . insertViews = null ;
273
+ // Only test canLeave/canEnter if there is transition
274
+ let requiresTransition = ( ti . enteringRequiresTransition || ti . leavingRequiresTransition ) && enteringView !== leavingView ;
275
+ if ( requiresTransition ) {
276
+ // views have been initialized, now let's test
277
+ // to see if the transition is even allowed or not
278
+ return this . _viewTest ( enteringView , leavingView , ti ) ;
279
+
280
+ } else {
281
+ return this . _postViewInit ( enteringView , leavingView , ti , ti . resolve ) ;
282
+ }
283
+ }
276
284
277
- let enteringRequiresTransition = false ;
278
- let leavingRequiresTransition = false ;
285
+ _nextTI ( ) : TransitionInstruction {
286
+ const ti = this . _queue . shift ( ) ;
287
+ if ( ! ti ) {
288
+ return null ;
289
+ }
290
+ const viewsLength = this . _views . length ;
279
291
280
292
if ( isPresent ( ti . removeStart ) ) {
281
293
if ( ti . removeStart < 0 ) {
@@ -284,39 +296,59 @@ export class NavControllerBase extends Ion implements NavController {
284
296
if ( ti . removeCount < 0 ) {
285
297
ti . removeCount = ( viewsLength - ti . removeStart ) ;
286
298
}
287
-
288
- leavingRequiresTransition = ( ti . removeStart + ti . removeCount === viewsLength ) ;
289
-
290
- for ( var i = 0 ; i < ti . removeCount ; i ++ ) {
291
- destroyQueue . push ( this . _views [ i + ti . removeStart ] ) ;
292
- }
293
-
294
- for ( var i = viewsLength - 1 ; i >= 0 ; i -- ) {
295
- var view = this . _views [ i ] ;
296
- if ( destroyQueue . indexOf ( view ) < 0 && view !== leavingView ) {
297
- enteringView = view ;
298
- break ;
299
- }
300
- }
301
-
302
- // default the direction to "back"
303
- opts . direction = opts . direction || DIRECTION_BACK ;
299
+ ti . leavingRequiresTransition = ( ( ti . removeStart + ti . removeCount ) === viewsLength ) ;
304
300
}
305
301
306
- if ( insertViews ) {
302
+ if ( ti . insertViews ) {
307
303
// allow -1 to be passed in to auto push it on the end
308
304
// and clean up the index if it's larger then the size of the stack
309
305
if ( ti . insertStart < 0 || ti . insertStart > viewsLength ) {
310
306
ti . insertStart = viewsLength ;
311
307
}
308
+ ti . enteringRequiresTransition = ( ti . insertStart === viewsLength ) ;
309
+ }
310
+ return ti ;
311
+ }
312
312
313
- // only requires a transition if it's going at the end
314
- enteringRequiresTransition = ( ti . insertStart === viewsLength ) ;
315
-
313
+ _getEnteringView ( ti : TransitionInstruction , leavingView : ViewController ) : ViewController {
314
+ const insertViews = ti . insertViews ;
315
+ if ( insertViews ) {
316
316
// grab the very last view of the views to be inserted
317
317
// and initialize it as the new entering view
318
- enteringView = insertViews [ insertViews . length - 1 ] ;
318
+ return insertViews [ insertViews . length - 1 ] ;
319
+ }
319
320
321
+ const removeStart = ti . removeStart ;
322
+ if ( isPresent ( removeStart ) ) {
323
+ let views = this . _views ;
324
+ const removeEnd = removeStart + ti . removeCount ;
325
+ for ( var i = views . length - 1 ; i >= 0 ; i -- ) {
326
+ var view = views [ i ] ;
327
+ if ( ( i < removeStart || i >= removeEnd ) && view !== leavingView ) {
328
+ return view ;
329
+ }
330
+ }
331
+ }
332
+ return null ;
333
+ }
334
+
335
+ _postViewInit ( enteringView : ViewController , leavingView : ViewController , ti : TransitionInstruction , resolve : TransitionResolveFn ) : boolean {
336
+ const opts = ti . opts || { } ;
337
+
338
+ const insertViews = ti . insertViews ;
339
+ const removeStart = ti . removeStart ;
340
+
341
+ let destroyQueue : ViewController [ ] = [ ] ;
342
+
343
+ if ( isPresent ( removeStart ) ) {
344
+ for ( var i = 0 ; i < ti . removeCount ; i ++ ) {
345
+ destroyQueue . push ( this . _views [ i + removeStart ] ) ;
346
+ }
347
+ // default the direction to "back"
348
+ opts . direction = opts . direction || DIRECTION_BACK ;
349
+ }
350
+
351
+ if ( insertViews ) {
320
352
// manually set the new view's id if an id was passed in the options
321
353
if ( isPresent ( opts . id ) ) {
322
354
enteringView . id = opts . id ;
@@ -345,7 +377,7 @@ export class NavControllerBase extends Ion implements NavController {
345
377
}
346
378
}
347
379
348
- if ( enteringRequiresTransition ) {
380
+ if ( ti . enteringRequiresTransition ) {
349
381
// default to forward if not already set
350
382
opts . direction = opts . direction || DIRECTION_FORWARD ;
351
383
}
@@ -380,7 +412,7 @@ export class NavControllerBase extends Ion implements NavController {
380
412
}
381
413
destroyQueue . length = 0 ;
382
414
383
- if ( enteringRequiresTransition || leavingRequiresTransition && enteringView !== leavingView ) {
415
+ if ( ti . enteringRequiresTransition || ti . leavingRequiresTransition && enteringView !== leavingView ) {
384
416
// set which animation it should use if it wasn't set yet
385
417
if ( ! opts . animation ) {
386
418
if ( isPresent ( ti . removeStart ) ) {
@@ -391,7 +423,7 @@ export class NavControllerBase extends Ion implements NavController {
391
423
}
392
424
393
425
// huzzah! let us transition these views
394
- this . _transition ( enteringView , leavingView , opts , resolve , reject ) ;
426
+ this . _transition ( enteringView , leavingView , opts , resolve ) ;
395
427
396
428
} else {
397
429
// they're inserting/removing the views somewhere in the middle or
@@ -403,71 +435,10 @@ export class NavControllerBase extends Ion implements NavController {
403
435
return true ;
404
436
}
405
437
406
- _transition ( enteringView : ViewController , leavingView : ViewController , opts : NavOptions , resolve : TransitionResolveFn , reject : TransitionRejectFn ) : void {
407
- // figure out if this transition is the root one or a
408
- // child of a parent nav that has the root transition
409
- this . _trnsId = this . _trnsCtrl . getRootTrnsId ( this ) ;
410
- if ( this . _trnsId === null ) {
411
- // this is the root transition, meaning all child navs and their views
412
- // should be added as a child transition to this one
413
- this . _trnsId = this . _trnsCtrl . nextId ( ) ;
414
- }
415
-
416
- // create the transition options
417
- const animationOpts : AnimationOptions = {
418
- animation : opts . animation ,
419
- direction : opts . direction ,
420
- duration : ( opts . animate === false ? 0 : opts . duration ) ,
421
- easing : opts . easing ,
422
- isRTL : this . config . platform . isRTL ( ) ,
423
- ev : opts . ev ,
424
- } ;
425
-
426
- // create the transition animation from the TransitionController
427
- // this will either create the root transition, or add it as a child transition
428
- const trns = this . _trnsCtrl . get ( this . _trnsId , enteringView , leavingView , animationOpts ) ;
429
-
430
- // ensure any swipeback transitions are cleared out
431
- this . _sbTrns && this . _sbTrns . destroy ( ) ;
432
-
433
- if ( trns . parent ) {
434
- // this is important for later to know if there
435
- // are any more child tests to check for
436
- trns . parent . hasChildTrns = true ;
437
-
438
- } else {
439
- // this is the root transition
440
- if ( opts . progressAnimation ) {
441
- this . _sbTrns = trns ;
442
- }
443
- }
444
-
445
- trns . registerStart ( ( ) => {
446
- this . _trnsStart ( trns , enteringView , leavingView , opts , resolve ) ;
447
- if ( trns . parent ) {
448
- trns . parent . start ( ) ;
449
- }
450
- } ) ;
451
-
452
- if ( enteringView && isBlank ( enteringView . _state ) ) {
453
- // render the entering view, and all child navs and views
454
- // ******** DOM WRITE ****************
455
- this . _viewInit ( trns , enteringView , opts ) ;
456
- }
457
-
458
- // views have been initialized, now let's test
459
- // to see if the transition is even allowed or not
460
- const shouldContinue = this . _viewTest ( trns , enteringView , leavingView , opts , resolve , reject ) ;
461
- if ( shouldContinue ) {
462
- // synchronous and all tests passed! let's continue
463
- this . _postViewInit ( trns , enteringView , leavingView , opts , resolve ) ;
464
- }
465
- }
466
-
467
438
/**
468
439
* DOM WRITE
469
440
*/
470
- _viewInit ( trns : Transition , enteringView : ViewController , opts : NavOptions ) {
441
+ _viewInit ( enteringView : ViewController ) {
471
442
// entering view has not been initialized yet
472
443
const componentProviders = ReflectiveInjector . resolve ( [
473
444
{ provide : NavController , useValue : this } ,
@@ -482,8 +453,10 @@ export class NavControllerBase extends Ion implements NavController {
482
453
enteringView . _state = ViewState . INITIALIZED ;
483
454
}
484
455
485
- _viewTest ( trns : Transition , enteringView : ViewController , leavingView : ViewController , opts : NavOptions , resolve : TransitionResolveFn , reject : TransitionRejectFn ) : boolean {
456
+ _viewTest ( enteringView : ViewController , leavingView : ViewController , ti : TransitionInstruction ) : boolean {
486
457
const promises : Promise < any > [ ] = [ ] ;
458
+ const reject = ti . reject ;
459
+ const resolve = ti . resolve ;
487
460
488
461
if ( leavingView ) {
489
462
const leavingTestResult = leavingView . _lifecycleTest ( 'Leave' ) ;
@@ -495,7 +468,7 @@ export class NavControllerBase extends Ion implements NavController {
495
468
496
469
} else {
497
470
// synchronous reject
498
- reject ( ( leavingTestResult !== false ? leavingTestResult : `ionViewCanLeave rejected` ) , trns ) ;
471
+ reject ( ( leavingTestResult !== false ? leavingTestResult : `ionViewCanLeave rejected` ) ) ;
499
472
return false ;
500
473
}
501
474
}
@@ -511,7 +484,7 @@ export class NavControllerBase extends Ion implements NavController {
511
484
512
485
} else {
513
486
// synchronous reject
514
- reject ( ( enteringTestResult !== false ? enteringTestResult : `ionViewCanEnter rejected` ) , trns ) ;
487
+ reject ( ( enteringTestResult !== false ? enteringTestResult : `ionViewCanEnter rejected` ) ) ;
515
488
return false ;
516
489
}
517
490
}
@@ -521,26 +494,67 @@ export class NavControllerBase extends Ion implements NavController {
521
494
// darn, async promises, gotta wait for them to resolve
522
495
Promise . all ( promises ) . then ( ( ) => {
523
496
// all promises resolved! let's continue
524
- this . _postViewInit ( trns , enteringView , leavingView , opts , resolve ) ;
525
-
526
- } , ( rejectReason : any ) => {
527
- // darn, one of the promises was rejected!!
528
- reject ( rejectReason , trns ) ;
497
+ this . _postViewInit ( enteringView , leavingView , ti , resolve ) ;
529
498
530
499
} ) . catch ( ( rejectReason ) => {
531
- // idk, who knows
532
- reject ( rejectReason , trns ) ;
500
+ reject ( rejectReason ) ;
533
501
} ) ;
534
502
535
503
return false ;
536
504
}
537
505
538
506
// synchronous and all tests passed! let's move on already
507
+ this . _postViewInit ( enteringView , leavingView , ti , resolve ) ;
508
+
539
509
return true ;
540
510
}
541
511
542
- _postViewInit ( trns : Transition , enteringView : ViewController , leavingView : ViewController , opts : NavOptions , resolve : TransitionResolveFn ) : void {
543
- // passed both the enter and leave tests
512
+ _transition ( enteringView : ViewController , leavingView : ViewController , opts : NavOptions , resolve : TransitionResolveFn ) : void {
513
+ // figure out if this transition is the root one or a
514
+ // child of a parent nav that has the root transition
515
+ this . _trnsId = this . _trnsCtrl . getRootTrnsId ( this ) ;
516
+ if ( this . _trnsId === null ) {
517
+ // this is the root transition, meaning all child navs and their views
518
+ // should be added as a child transition to this one
519
+ this . _trnsId = this . _trnsCtrl . nextId ( ) ;
520
+ }
521
+
522
+ // create the transition options
523
+ const animationOpts : AnimationOptions = {
524
+ animation : opts . animation ,
525
+ direction : opts . direction ,
526
+ duration : ( opts . animate === false ? 0 : opts . duration ) ,
527
+ easing : opts . easing ,
528
+ isRTL : this . config . platform . isRTL ( ) ,
529
+ ev : opts . ev ,
530
+ } ;
531
+
532
+ // create the transition animation from the TransitionController
533
+ // this will either create the root transition, or add it as a child transition
534
+ const trns = this . _trnsCtrl . get ( this . _trnsId , enteringView , leavingView , animationOpts ) ;
535
+
536
+ // ensure any swipeback transitions are cleared out
537
+ this . _sbTrns && this . _sbTrns . destroy ( ) ;
538
+
539
+ if ( trns . parent ) {
540
+ // this is important for later to know if there
541
+ // are any more child tests to check for
542
+ trns . parent . hasChildTrns = true ;
543
+
544
+ } else {
545
+ // this is the root transition
546
+ if ( opts . progressAnimation ) {
547
+ this . _sbTrns = trns ;
548
+ }
549
+ }
550
+
551
+ trns . registerStart ( ( ) => {
552
+ this . _trnsStart ( trns , enteringView , leavingView , opts , resolve ) ;
553
+ if ( trns . parent ) {
554
+ trns . parent . start ( ) ;
555
+ }
556
+ } ) ;
557
+
544
558
if ( enteringView && enteringView . _state === ViewState . INITIALIZED ) {
545
559
// render the entering component in the DOM
546
560
// this would also render new child navs/views
0 commit comments