@@ -80,10 +80,19 @@ function UrlMatcher(pattern, config) {
8080 segments = this . segments = [ ] ,
8181 params = this . params = { } ;
8282
83+ /**
84+ * [Internal] Gets the decoded representation of a value if the value is defined, otherwise, returns the
85+ * default value, which may be the result of an injectable function.
86+ */
87+ function $value ( value ) {
88+ /*jshint validthis: true */
89+ return isDefined ( value ) ? this . type . decode ( value ) : $UrlMatcherFactory . $$getDefaultValue ( this ) ;
90+ }
91+
8392 function addParameter ( id , type , config ) {
8493 if ( ! / ^ \w + ( - + \w + ) * $ / . test ( id ) ) throw new Error ( "Invalid parameter name '" + id + "' in pattern '" + pattern + "'" ) ;
8594 if ( params [ id ] ) throw new Error ( "Duplicate parameter name '" + id + "' in pattern '" + pattern + "'" ) ;
86- params [ id ] = extend ( { type : type || new Type ( ) } , config ) ;
95+ params [ id ] = extend ( { type : type || new Type ( ) , $value : $value } , config ) ;
8796 }
8897
8998 function quoteRegExp ( string , pattern , isOptional ) {
@@ -216,7 +225,7 @@ UrlMatcher.prototype.exec = function (path, searchParams) {
216225 for ( i = 0 ; i < nPath ; i ++ ) {
217226 param = params [ i ] ;
218227 cfg = this . params [ param ] ;
219- values [ param ] = isDefined ( m [ i + 1 ] ) ? cfg . type . decode ( m [ i + 1 ] ) : cfg . value ;
228+ values [ param ] = cfg . $value ( m [ i + 1 ] ) ;
220229 }
221230 for ( /**/ ; i < nTotal ; i ++ ) {
222231 param = params [ i ] ;
@@ -483,6 +492,19 @@ function $UrlMatcherFactory() {
483492 } ;
484493 }
485494
495+ function isInjectable ( value ) {
496+ return ( isFunction ( value ) || ( isArray ( value ) && isFunction ( value [ value . length - 1 ] ) ) ) ;
497+ }
498+
499+ /**
500+ * [Internal] Get the default value of a parameter, which may be an injectable function.
501+ */
502+ $UrlMatcherFactory . $$getDefaultValue = function ( config ) {
503+ if ( ! isInjectable ( config . value ) ) return config . value ;
504+ if ( ! injector ) throw new Error ( "Injectable functions cannot be called at configuration time" ) ;
505+ return injector . invoke ( config . value ) ;
506+ } ;
507+
486508 /**
487509 * @ngdoc function
488510 * @name ui.router.util.$urlMatcherFactory#caseInsensitive
@@ -683,8 +705,7 @@ function $UrlMatcherFactory() {
683705 if ( UrlMatcher . prototype . $types [ type . name ] ) {
684706 throw new Error ( "A type named '" + type . name + "' has already been defined." ) ;
685707 }
686- var isAnnotated = isFunction ( type . def ) || isArray ( type . def ) ;
687- var def = new Type ( isAnnotated ? injector . invoke ( type . def ) : type . def ) ;
708+ var def = new Type ( isInjectable ( type . def ) ? injector . invoke ( type . def ) : type . def ) ;
688709 UrlMatcher . prototype . $types [ type . name ] = def ;
689710 } ) ;
690711 }
0 commit comments