diff --git a/modules/directives/route/route.js b/modules/directives/route/route.js new file mode 100644 index 0000000..19029cb --- /dev/null +++ b/modules/directives/route/route.js @@ -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', + 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(); + }); + } + } + }; +}]); \ No newline at end of file diff --git a/modules/directives/route/test/routeSpec.js b/modules/directives/route/test/routeSpec.js new file mode 100644 index 0000000..cdc7511 --- /dev/null +++ b/modules/directives/route/test/routeSpec.js @@ -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('
')(scope); + }); + it('should update $uiRoute on $observe', function(){ + setPath('/bar'); + scope.$apply('foobar = "foo"'); + $compile('
')(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('
')(scope); + expect(scope.$uiRoute).toBe(true); + }); + }); + + describe('with ngHref defined', function(){ + + iit('should use the ngHref property', function(){ + setPath('/foo'); + $compile('')(scope); + expect(scope.$uiRoute).toBe(true); + }); + it('should update $uiRoute on $observe', function(){ + setPath('/bar'); + scope.$apply('foobar = "foo"'); + $compile('')(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('')(scope); + expect(scope.$uiRoute).toBe(true); + }); + }); + + it('should throw an error if no route property available', function(){ + expect(function(){ + $compile('
')(scope); + }).toThrow(); + }); + + it('should update $uiRoute on route change', function(){ + setPath('/bar'); + $compile('
')(scope); + expect(scope.$uiRoute).toBeFalsy(); + setPath('/foo'); + expect(scope.$uiRoute).toBe(true); + setPath('/bar'); + expect(scope.$uiRoute).toBe(false); + }); +}); \ No newline at end of file