Skip to content
This repository was archived by the owner on Feb 19, 2025. It is now read-only.
67 changes: 67 additions & 0 deletions modules/directives/route/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* Set a $uiRoute boolean to see if the current route matches
*/
angular.module('ui.directives').directive('uiRoute', ['$location', function ($location) {
return {
restrict: 'AC',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably should restrict A

compile: function(tElement, tAttrs) {
var useProperty;
if (tAttrs.uiRoute) {
useProperty = 'uiRoute';
} else if (tAttrs.ngHref) {
useProperty = 'ngHref';
} else if (tAttrs.href) {
useProperty = 'href';
} else {
throw new Error('uiRoute missing a route or href property on ' + elm[0]);
}
return function ($scope, elm, attrs) {
var watcher = angular.noop;

// Used by href and ngHref
function staticWatcher(newVal) {
if ((hash = newVal.indexOf('#')) > -1)
newVal = newVal.substr(hash + 1);
watcher = function watchHref() {
$scope.$uiRoute = ($location.path().indexOf(newVal) > -1);
};
watcher();
}
// Used by uiRoute
function regexWatcher(newVal) {
if ((hash = newVal.indexOf('#')) > -1)
newVal = newVal.substr(hash + 1);
watcher = function watchRegex() {
var regexp = new RegExp('^' + newVal + '$', ['i']);
$scope.$uiRoute = regexp.test($location.path());
};
watcher();
}

switch (useProperty) {
case 'uiRoute':
// if uiRoute={{}} this will be undefined, otherwise it will have a value and $observe() never gets triggered
if (attrs.uiRoute)
regexWatcher(attrs.uiRoute);
else
attrs.$observe('uiRoute', regexWatcher);
break;
case 'ngHref':
// Setup watcher() every time ngHref changes
if (attrs.ngHref)
staticWatcher(attrs.ngHref);
else
attrs.$observe('ngHref', staticWatcher);
break;
case 'href':
// Setup watcher()
staticWatcher(attrs.href);
}

$scope.$on('$routeChangeSuccess', function(){
watcher();
});
}
}
};
}]);
83 changes: 83 additions & 0 deletions modules/directives/route/test/routeSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*global describe, beforeEach, module, inject, it, spyOn, expect, $ */
describe('uiRoute', function () {
'use strict';

var scope, $compile, $location;
beforeEach(module('ui.directives'));
beforeEach(inject(function (_$rootScope_, _$compile_, _$window_, _$location_) {
scope = _$rootScope_.$new();
$compile = _$compile_;
$location = _$location_;
}));

function setPath(path) {
$location.path(path);
scope.$broadcast('$routeChangeSuccess');
scope.$apply();
}

describe('with uiRoute defined', function(){
it('should use the uiRoute property', function(){
$compile('<div ui-route="/foo" />')(scope);
});
it('should update $uiRoute on $observe', function(){
setPath('/bar');
scope.$apply('foobar = "foo"');
$compile('<div ui-route="/{{foobar}}" />')(scope);
expect(scope.$uiRoute).toBeFalsy();
scope.$apply('foobar = "bar"');
expect(scope.$uiRoute).toBe(true);
scope.$apply('foobar = "foo"');
expect(scope.$uiRoute).toBe(false);
});
it('should support regular expression', function(){
setPath('/foo/123');
$compile('<div ui-route="/foo/[0-9]*" />')(scope);
expect(scope.$uiRoute).toBe(true);
});
});

describe('with ngHref defined', function(){

iit('should use the ngHref property', function(){
setPath('/foo');
$compile('<a ng-href="/foo" ui-route />')(scope);
expect(scope.$uiRoute).toBe(true);
});
it('should update $uiRoute on $observe', function(){
setPath('/bar');
scope.$apply('foobar = "foo"');
$compile('<a ng-href="/{{foobar}}" ui-route />')(scope);
expect(scope.$uiRoute).toBeFalsy();
scope.$apply('foobar = "bar"');
expect(scope.$uiRoute).toBe(true);
scope.$apply('foobar = "foo"');
expect(scope.$uiRoute).toBe(false);
});
});

describe('with href defined', function(){

it('should use the href property', function(){
setPath('/foo');
$compile('<a href="/foo" ui-route />')(scope);
expect(scope.$uiRoute).toBe(true);
});
});

it('should throw an error if no route property available', function(){
expect(function(){
$compile('<div ui-route/>')(scope);
}).toThrow();
});

it('should update $uiRoute on route change', function(){
setPath('/bar');
$compile('<div ui-route="/foo" />')(scope);
expect(scope.$uiRoute).toBeFalsy();
setPath('/foo');
expect(scope.$uiRoute).toBe(true);
setPath('/bar');
expect(scope.$uiRoute).toBe(false);
});
});