@@ -480,6 +480,11 @@ Type.prototype.pattern = /.*/;
480
480
481
481
Type . prototype . toString = function ( ) { return "{Type:" + this . name + "}" ; } ;
482
482
483
+ /** Given an encoded string, or a decoded object, returns a decoded object */
484
+ Type . prototype . $normalize = function ( val ) {
485
+ return this . is ( val ) ? val : this . decode ( val ) ;
486
+ } ;
487
+
483
488
/*
484
489
* Wraps an existing custom Type as an array of Type, depending on 'mode'.
485
490
* e.g.:
@@ -493,7 +498,6 @@ Type.prototype.toString = function() { return "{Type:" + this.name + "}"; };
493
498
Type . prototype . $asArray = function ( mode , isSearch ) {
494
499
if ( ! mode ) return this ;
495
500
if ( mode === "auto" && ! isSearch ) throw new Error ( "'auto' array mode is for query parameters only" ) ;
496
- return new ArrayType ( this , mode ) ;
497
501
498
502
function ArrayType ( type , mode ) {
499
503
function bindTo ( type , callbackName ) {
@@ -542,8 +546,12 @@ Type.prototype.$asArray = function(mode, isSearch) {
542
546
this . is = arrayHandler ( bindTo ( type , 'is' ) , true ) ;
543
547
this . equals = arrayEqualsHandler ( bindTo ( type , 'equals' ) ) ;
544
548
this . pattern = type . pattern ;
549
+ this . $normalize = arrayHandler ( bindTo ( type , '$normalize' ) ) ;
550
+ this . name = type . name ;
545
551
this . $arrayMode = mode ;
546
552
}
553
+
554
+ return new ArrayType ( this , mode ) ;
547
555
} ;
548
556
549
557
@@ -571,7 +579,7 @@ function $UrlMatcherFactory() {
571
579
string : {
572
580
encode : valToString ,
573
581
decode : valFromString ,
574
- is : regexpMatches ,
582
+ is : function ( val ) { return typeof val === "string" } ,
575
583
pattern : / [ ^ / ] * /
576
584
} ,
577
585
int : {
@@ -945,7 +953,10 @@ function $UrlMatcherFactory() {
945
953
*/
946
954
function $$getDefaultValue ( ) {
947
955
if ( ! injector ) throw new Error ( "Injectable functions cannot be called at configuration time" ) ;
948
- return injector . invoke ( config . $$fn ) ;
956
+ var defaultValue = injector . invoke ( config . $$fn ) ;
957
+ if ( defaultValue !== null && defaultValue !== undefined && ! self . type . is ( defaultValue ) )
958
+ throw new Error ( "Default value (" + defaultValue + ") for parameter '" + self . id + "' is not an instance of Type (" + self . type . name + ")" ) ;
959
+ return defaultValue ;
949
960
}
950
961
951
962
/**
@@ -959,7 +970,7 @@ function $UrlMatcherFactory() {
959
970
return replacement . length ? replacement [ 0 ] : value ;
960
971
}
961
972
value = $replace ( value ) ;
962
- return isDefined ( value ) ? self . type . decode ( value ) : $$getDefaultValue ( ) ;
973
+ return ! isDefined ( value ) ? $$getDefaultValue ( ) : self . type . $normalize ( value ) ;
963
974
}
964
975
965
976
function toString ( ) { return "{Param:" + id + " " + type + " squash: '" + squash + "' optional: " + isOptional + "}" ; }
@@ -1015,15 +1026,20 @@ function $UrlMatcherFactory() {
1015
1026
return equal ;
1016
1027
} ,
1017
1028
$$validates : function $$validate ( paramValues ) {
1018
- var result = true , isOptional , val , param , self = this ;
1019
-
1020
- forEach ( this . $$keys ( ) , function ( key ) {
1021
- param = self [ key ] ;
1022
- val = paramValues [ key ] ;
1023
- isOptional = ! val && param . isOptional ;
1024
- result = result && ( isOptional || ! ! param . type . is ( val ) ) ;
1025
- } ) ;
1026
- return result ;
1029
+ var keys = this . $$keys ( ) , i , param , rawVal , normalized , encoded ;
1030
+ for ( i = 0 ; i < keys . length ; i ++ ) {
1031
+ param = this [ keys [ i ] ] ;
1032
+ rawVal = paramValues [ keys [ i ] ] ;
1033
+ if ( ( rawVal === undefined || rawVal === null ) && param . isOptional )
1034
+ break ; // There was no parameter value, but the param is optional
1035
+ normalized = param . type . $normalize ( rawVal ) ;
1036
+ if ( ! param . type . is ( normalized ) )
1037
+ return false ; // The value was not of the correct Type, and could not be decoded to the correct Type
1038
+ encoded = param . type . encode ( normalized ) ;
1039
+ if ( angular . isString ( encoded ) && ! param . type . pattern . exec ( encoded ) )
1040
+ return false ; // The value was of the correct type, but when encoded, did not match the Type's regexp
1041
+ }
1042
+ return true ;
1027
1043
} ,
1028
1044
$$parent : undefined
1029
1045
} ;
0 commit comments