@@ -27,6 +27,11 @@ var numberOfContextsAcceptedByHandler = function(handler, handlerInfos) {
27
27
return req ;
28
28
} ;
29
29
30
+ var linkViewClassNameBindings = [ 'active' , 'loading' , 'disabled' ] ;
31
+ if ( Ember . FEATURES . isEnabled ( 'ember-routing-transitioning-classes' ) ) {
32
+ linkViewClassNameBindings = [ 'active' , 'loading' , 'disabled' , 'transitioningIn' , 'transitioningOut' ] ;
33
+ }
34
+
30
35
/**
31
36
`Ember.LinkView` renders an element whose `click` event triggers a
32
37
transition of the application's instance of `Ember.Router` to
@@ -149,7 +154,7 @@ var LinkView = Ember.LinkView = EmberComponent.extend({
149
154
@type Array
150
155
@default ['active', 'loading', 'disabled']
151
156
**/
152
- classNameBindings : [ 'active' , 'loading' , 'disabled' ] ,
157
+ classNameBindings : linkViewClassNameBindings ,
153
158
154
159
/**
155
160
By default the `{{link-to}}` helper responds to the `click` event. You
@@ -289,56 +294,32 @@ var LinkView = Ember.LinkView = EmberComponent.extend({
289
294
@property active
290
295
**/
291
296
active : computed ( 'loadedParams' , function computeLinkViewActive ( ) {
292
- if ( get ( this , 'loading' ) ) { return false ; }
297
+ var router = get ( this , 'router' ) ;
298
+ if ( ! router ) { return ; }
299
+ return computeActive ( this , router . currentState ) ;
300
+ } ) ,
293
301
302
+ willBeActive : computed ( 'router.targetState' , function ( ) {
294
303
var router = get ( this , 'router' ) ;
295
- var loadedParams = get ( this , 'loadedParams' ) ;
296
- var contexts = loadedParams . models ;
297
- var currentWhen = this [ 'current-when' ] || this . currentWhen ;
298
- var isCurrentWhenSpecified = Boolean ( currentWhen ) ;
299
- currentWhen = currentWhen || loadedParams . targetRouteName ;
300
-
301
- function isActiveForRoute ( routeName ) {
302
- var handlers = router . router . recognizer . handlersFor ( routeName ) ;
303
- var leafName = handlers [ handlers . length - 1 ] . handler ;
304
- var maximumContexts = numberOfContextsAcceptedByHandler ( routeName , handlers ) ;
305
-
306
- // NOTE: any ugliness in the calculation of activeness is largely
307
- // due to the fact that we support automatic normalizing of
308
- // `resource` -> `resource.index`, even though there might be
309
- // dynamic segments / query params defined on `resource.index`
310
- // which complicates (and makes somewhat ambiguous) the calculation
311
- // of activeness for links that link to `resource` instead of
312
- // directly to `resource.index`.
313
-
314
- // if we don't have enough contexts revert back to full route name
315
- // this is because the leaf route will use one of the contexts
316
- if ( contexts . length > maximumContexts ) {
317
- routeName = leafName ;
318
- }
304
+ if ( ! router ) { return ; }
305
+ var targetState = router . targetState ;
306
+ if ( router . currentState === targetState ) { return ; }
319
307
320
- var args = routeArgs ( routeName , contexts , null ) ;
321
- var isActive = router . isActive . apply ( router , args ) ;
322
- if ( ! isActive ) { return false ; }
308
+ return ! ! computeActive ( this , targetState ) ;
309
+ } ) ,
323
310
324
- var emptyQueryParams = Ember . isEmpty ( Ember . keys ( loadedParams . queryParams ) ) ;
311
+ transitioningIn : computed ( 'active' , 'willBeActive' , function ( ) {
312
+ var willBeActive = get ( this , 'willBeActive' ) ;
313
+ if ( typeof willBeActive === 'undefined' ) { return false ; }
325
314
326
- if ( ! isCurrentWhenSpecified && ! emptyQueryParams && isActive ) {
327
- var visibleQueryParams = { } ;
328
- merge ( visibleQueryParams , loadedParams . queryParams ) ;
329
- router . _prepareQueryParams ( loadedParams . targetRouteName , loadedParams . models , visibleQueryParams ) ;
330
- isActive = shallowEqual ( visibleQueryParams , router . router . state . queryParams ) ;
331
- }
315
+ return ! get ( this , 'active' ) && willBeActive ;
316
+ } ) ,
332
317
333
- return isActive ;
334
- }
318
+ transitioningOut : computed ( 'active' , 'willBeActive' , function ( ) {
319
+ var willBeActive = get ( this , 'willBeActive' ) ;
320
+ if ( typeof willBeActive === 'undefined' ) { return false ; }
335
321
336
- currentWhen = currentWhen . split ( ' ' ) ;
337
- for ( var i = 0 , len = currentWhen . length ; i < len ; i ++ ) {
338
- if ( isActiveForRoute ( currentWhen [ i ] ) ) {
339
- return get ( this , 'activeClass' ) ;
340
- }
341
- }
322
+ return get ( this , 'active' ) && ! willBeActive ;
342
323
} ) ,
343
324
344
325
/**
@@ -408,6 +389,10 @@ var LinkView = Ember.LinkView = EmberComponent.extend({
408
389
transition . method ( 'replace' ) ;
409
390
}
410
391
392
+ if ( Ember . FEATURES . isEnabled ( 'ember-routing-transitioning-classes' ) ) {
393
+ return ;
394
+ }
395
+
411
396
// Schedule eager URL update, but after we've given the transition
412
397
// a chance to synchronously redirect.
413
398
// We need to always generate the URL instead of using the href because
@@ -591,15 +576,44 @@ function paramsAreLoaded(params) {
591
576
return true ;
592
577
}
593
578
594
- function shallowEqual ( a , b ) {
595
- var k ;
596
- for ( k in a ) {
597
- if ( a . hasOwnProperty ( k ) && a [ k ] !== b [ k ] ) { return false ; }
579
+ function computeActive ( route , routerState ) {
580
+ if ( get ( route , 'loading' ) ) { return false ; }
581
+
582
+ var currentWhen = route [ 'current-when' ] || route . currentWhen ;
583
+ var isCurrentWhenSpecified = ! ! currentWhen ;
584
+ currentWhen = currentWhen || get ( route , 'loadedParams' ) . targetRouteName ;
585
+ currentWhen = currentWhen . split ( ' ' ) ;
586
+ for ( var i = 0 , len = currentWhen . length ; i < len ; i ++ ) {
587
+ if ( isActiveForRoute ( route , currentWhen [ i ] , isCurrentWhenSpecified , routerState ) ) {
588
+ return get ( route , 'activeClass' ) ;
589
+ }
598
590
}
599
- for ( k in b ) {
600
- if ( b . hasOwnProperty ( k ) && a [ k ] !== b [ k ] ) { return false ; }
591
+ }
592
+
593
+ function isActiveForRoute ( route , routeName , isCurrentWhenSpecified , routerState ) {
594
+ var router = get ( route , 'router' ) ;
595
+ var loadedParams = get ( route , 'loadedParams' ) ;
596
+ var contexts = loadedParams . models ;
597
+
598
+ var handlers = router . router . recognizer . handlersFor ( routeName ) ;
599
+ var leafName = handlers [ handlers . length - 1 ] . handler ;
600
+ var maximumContexts = numberOfContextsAcceptedByHandler ( routeName , handlers ) ;
601
+
602
+ // NOTE: any ugliness in the calculation of activeness is largely
603
+ // due to the fact that we support automatic normalizing of
604
+ // `resource` -> `resource.index`, even though there might be
605
+ // dynamic segments / query params defined on `resource.index`
606
+ // which complicates (and makes somewhat ambiguous) the calculation
607
+ // of activeness for links that link to `resource` instead of
608
+ // directly to `resource.index`.
609
+
610
+ // if we don't have enough contexts revert back to full route name
611
+ // this is because the leaf route will use one of the contexts
612
+ if ( contexts . length > maximumContexts ) {
613
+ routeName = leafName ;
601
614
}
602
- return true ;
615
+
616
+ return routerState . isActiveIntent ( routeName , contexts , loadedParams . queryParams , ! isCurrentWhenSpecified ) ;
603
617
}
604
618
605
619
export {
0 commit comments