Skip to content

Commit

Permalink
fix(uiSrefActive): don't match fuzzy on lazy loaded future states
Browse files Browse the repository at this point in the history
  • Loading branch information
fpipita committed Jan 26, 2018
1 parent b92a07c commit 01430ee
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 12 deletions.
44 changes: 32 additions & 12 deletions src/directives/stateDirectives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ uiSrefActiveDirective = ['$state', '$stateParams', '$interpolate', '$uiRouter',
restrict: 'A',
controller: ['$scope', '$element', '$attrs',
function ($scope: IScope, $element: IAugmentedJQuery, $attrs: any) {
const states: StateData[] = [];
let states: StateData[] = [];
let activeEqClass: string;
let uiSrefActive: any;

Expand All @@ -543,15 +543,10 @@ uiSrefActiveDirective = ['$state', '$stateParams', '$interpolate', '$uiRouter',
// Do nothing. uiSrefActive is not a valid expression.
// Fall back to using $interpolate below
}
uiSrefActive = uiSrefActive || $interpolate($attrs.uiSrefActive || '', false)($scope);
if (isObject(uiSrefActive)) {
forEach(uiSrefActive, function (stateOrName: StateOrName, activeClass: string) {
if (isString(stateOrName)) {
const ref = parseStateRef(stateOrName);
addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
}
});
if (!uiSrefActive) {
uiSrefActive = $interpolate($attrs.uiSrefActive || '', false)($scope);
}
setStatesFromDefinitionObject(uiSrefActive);

// Allow uiSref to communicate with uiSrefActive[Equals]
this.$$addStateInfo = function (newState: string, newParams: Obj) {
Expand All @@ -568,13 +563,38 @@ uiSrefActiveDirective = ['$state', '$stateParams', '$interpolate', '$uiRouter',
function updateAfterTransition(trans) {
trans.promise.then(update, noop);
}

$scope.$on('$stateChangeSuccess', update);
$scope.$on('$destroy', <any> $uiRouter.transitionService.onStart({}, updateAfterTransition));
$scope.$on('$destroy', setupEventListeners());
if ($uiRouter.globals.transition) {
updateAfterTransition($uiRouter.globals.transition);
}

function setupEventListeners () {
const deregisterStatesChangedListener = $uiRouter.stateRegistry.onStatesChanged(handleStatesChanged);
const deregisterOnStartListener = $uiRouter.transitionService.onStart({}, updateAfterTransition);
const deregisterStateChangeSuccessListener = $scope.$on('$stateChangeSuccess', update);
return function cleanUp () {
deregisterStatesChangedListener();
deregisterOnStartListener();
deregisterStateChangeSuccessListener();
};
}

function handleStatesChanged () {
setStatesFromDefinitionObject(uiSrefActive);
}

function setStatesFromDefinitionObject (statesDefinition: any) {
if (isObject(statesDefinition)) {
states = [];
forEach(statesDefinition, function (stateOrName: StateOrName, activeClass: string) {
if (isString(stateOrName)) {
const ref = parseStateRef(stateOrName);
addState(ref.state, $scope.$eval(ref.paramExpr), activeClass);
}
});
}
}

function addState(stateName: string, stateParams: Obj, activeClass: string) {
const state = $state.get(stateName, stateContext($element));

Expand Down
50 changes: 50 additions & 0 deletions test/stateDirectivesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,31 @@ describe('uiSrefActive', function() {
expect(a.attr('class')).toMatch(/active also-active/);
}));

it('should not match fuzzy on lazy loaded future states', inject(function($rootScope, $compile, $q, $state) {
_stateProvider.state('contacts.lazy.**', {
url: '/lazy',
lazyLoad: function() {
return $q.when().then(function() {
_stateProvider.state('contacts.lazy', {
abstract: true,
url: '/lazy'
}).state('contacts.lazy.s1', {
url: '/s1'
}).state('contacts.lazy.s2', {
url: '/s2'
});
});
}
});
template = $compile('<div ui-sref-active="active"><a ui-sref="contacts.lazy.s1">Lazy</a></div><div ui-sref-active="active"><a ui-sref="contacts.lazy.s2"></a></div>')($rootScope);
$rootScope.$digest();
$state.transitionTo('contacts.lazy.s1');
$q.flush();
timeoutFlush();
expect(template.eq(0).hasClass('active')).toBeTruthy();
expect(template.eq(1).hasClass('active')).toBeFalsy();
}));

describe('ng-{class,style} interface', function() {
it('should match on abstract states that are included by the current state', inject(function($rootScope, $compile, $state, $q) {
el = $compile('<div ui-sref-active="{active: \'admin.*\'}"><a ui-sref-active="active" ui-sref="admin.roles">Roles</a></div>')($rootScope);
Expand Down Expand Up @@ -1111,5 +1136,30 @@ describe('uiSrefActive', function() {
timeoutFlush();
expect(el.hasClass('active')).toBeTruthy();
}));

it('should not match fuzzy on lazy loaded future states', inject(function($rootScope, $compile, $q, $state) {
_stateProvider.state('contacts.lazy.**', {
url: '/lazy',
lazyLoad: function() {
return $q.when().then(function() {
_stateProvider.state('contacts.lazy', {
abstract: true,
url: '/lazy'
}).state('contacts.lazy.s1', {
url: '/s1'
}).state('contacts.lazy.s2', {
url: '/s2'
});
});
}
});
template = $compile('<div ui-sref-active="{ active: \'contacts.lazy.s1\' }"><a ui-sref="contacts.lazy.s1">Lazy</a></div><div ui-sref-active="{ active: \'contacts.lazy.s2\' }"></div>')($rootScope);
$rootScope.$digest();
$state.transitionTo('contacts.lazy.s1');
$q.flush();
timeoutFlush();
expect(template.eq(0).hasClass('active')).toBeTruthy();
expect(template.eq(1).hasClass('active')).toBeFalsy();
}));
});
});

0 comments on commit 01430ee

Please sign in to comment.