@@ -80,7 +80,7 @@ function $StateRefDirective($state, $timeout) {
8080
8181 return {
8282 restrict : 'A' ,
83- require : '?^uiSrefActive' ,
83+ require : [ '?^uiSrefActive' , '?^uiSrefActiveEq' ] ,
8484 link : function ( scope , element , attrs , uiSrefActive ) {
8585 var ref = parseStateRef ( attrs . uiSref ) ;
8686 var params = null , url = null , base = stateContext ( element ) || $state . $current ;
@@ -103,8 +103,9 @@ function $StateRefDirective($state, $timeout) {
103103
104104 var newHref = $state . href ( ref . state , params , options ) ;
105105
106- if ( uiSrefActive ) {
107- uiSrefActive . $$setStateInfo ( ref . state , params ) ;
106+ var activeDirective = uiSrefActive [ 1 ] || uiSrefActive [ 0 ] ;
107+ if ( activeDirective ) {
108+ activeDirective . $$setStateInfo ( ref . state , params ) ;
108109 }
109110 if ( ! newHref ) {
110111 nav = false ;
@@ -148,12 +149,20 @@ function $StateRefDirective($state, $timeout) {
148149 * @restrict A
149150 *
150151 * @description
151- * A directive working alongside ui-sref to add classes to an element when the
152+ * A directive working alongside ui-sref to add classes to an element when the
152153 * related ui-sref directive's state is active, and removing them when it is inactive.
153- * The primary use-case is to simplify the special appearance of navigation menus
154+ * The primary use-case is to simplify the special appearance of navigation menus
154155 * relying on `ui-sref`, by having the "active" state's menu button appear different,
155156 * distinguishing it from the inactive menu items.
156157 *
158+ * ui-sref-active can live on the same element as ui-sref or on a parent element. The first
159+ * ui-sref-active found at the same level or above the ui-sref will be used.
160+ *
161+ * Will activate when the ui-sref's target state or any child state is active. If you
162+ * need to activate only when the ui-sref target state is active and *not* any of
163+ * it's children, then you will use
164+ * {@link ui.router.state.directive:ui-sref-active-eq ui-sref-active-eq}
165+ *
157166 * @example
158167 * Given the following template:
159168 * <pre>
@@ -163,8 +172,9 @@ function $StateRefDirective($state, $timeout) {
163172 * </li>
164173 * </ul>
165174 * </pre>
166- *
167- * When the app state is "app.user", and contains the state parameter "user" with value "bilbobaggins",
175+ *
176+ *
177+ * When the app state is "app.user" (or any children states), and contains the state parameter "user" with value "bilbobaggins",
168178 * the resulting HTML will appear as (note the 'active' class):
169179 * <pre>
170180 * <ul>
@@ -173,10 +183,10 @@ function $StateRefDirective($state, $timeout) {
173183 * </li>
174184 * </ul>
175185 * </pre>
176- *
177- * The class name is interpolated **once** during the directives link time (any further changes to the
178- * interpolated value are ignored).
179- *
186+ *
187+ * The class name is interpolated **once** during the directives link time (any further changes to the
188+ * interpolated value are ignored).
189+ *
180190 * Multiple classes may be specified in a space-separated format:
181191 * <pre>
182192 * <ul>
@@ -186,18 +196,36 @@ function $StateRefDirective($state, $timeout) {
186196 * </ul>
187197 * </pre>
188198 */
189- $StateActiveDirective . $inject = [ '$state' , '$stateParams' , '$interpolate' ] ;
190- function $StateActiveDirective ( $state , $stateParams , $interpolate ) {
191- return {
199+
200+ /**
201+ * @ngdoc directive
202+ * @name ui.router.state.directive:ui-sref-active-eq
203+ *
204+ * @requires ui.router.state.$state
205+ * @requires ui.router.state.$stateParams
206+ * @requires $interpolate
207+ *
208+ * @restrict A
209+ *
210+ * @description
211+ * The same as {@link ui.router.state.directive:ui-sref-active ui-sref-active} but will will only activate
212+ * when the exact target state used in the `ui-sref` is active; no child states.
213+ *
214+ */
215+ $StateRefActiveDirective . $inject = [ '$state' , '$stateParams' , '$interpolate' ] ;
216+ function $StateRefActiveDirective ( $state , $stateParams , $interpolate ) {
217+ return {
192218 restrict : "A" ,
193- controller : [ '$scope' , '$element' , '$attrs' , function ( $scope , $element , $attrs ) {
219+ controller : [ '$scope' , '$element' , '$attrs' , function ( $scope , $element , $attrs ) {
194220 var state , params , activeClass ;
195221
196222 // There probably isn't much point in $observing this
197- activeClass = $interpolate ( $attrs . uiSrefActive || '' , false ) ( $scope ) ;
223+ // uiSrefActive and uiSrefActiveEq share the same directive object with some
224+ // slight difference in logic routing
225+ activeClass = $interpolate ( $attrs . uiSrefActiveEq || $attrs . uiSrefActive || '' , false ) ( $scope ) ;
198226
199- // Allow uiSref to communicate with uiSrefActive
200- this . $$setStateInfo = function ( newState , newParams ) {
227+ // Allow uiSref to communicate with uiSrefActive[Equals]
228+ this . $$setStateInfo = function ( newState , newParams ) {
201229 state = $state . get ( newState , stateContext ( $element ) ) ;
202230 params = newParams ;
203231 update ( ) ;
@@ -207,13 +235,21 @@ function $StateActiveDirective($state, $stateParams, $interpolate) {
207235
208236 // Update route state
209237 function update ( ) {
210- if ( $state . $current . self === state && matchesParams ( ) ) {
238+ if ( isMatch ( ) ) {
211239 $element . addClass ( activeClass ) ;
212240 } else {
213241 $element . removeClass ( activeClass ) ;
214242 }
215243 }
216244
245+ function isMatch ( ) {
246+ if ( typeof $attrs . uiSrefActiveEq !== 'undefined' ) {
247+ return $state . $current . self === state && matchesParams ( ) ;
248+ } else {
249+ return $state . includes ( state . name ) && matchesParams ( ) ;
250+ }
251+ }
252+
217253 function matchesParams ( ) {
218254 return ! params || equalForKeys ( params , $stateParams ) ;
219255 }
@@ -223,4 +259,5 @@ function $StateActiveDirective($state, $stateParams, $interpolate) {
223259
224260angular . module ( 'ui.router.state' )
225261 . directive ( 'uiSref' , $StateRefDirective )
226- . directive ( 'uiSrefActive' , $StateActiveDirective ) ;
262+ . directive ( 'uiSrefActive' , $StateRefActiveDirective )
263+ . directive ( 'uiSrefActiveEq' , $StateRefActiveDirective ) ;
0 commit comments