@@ -454,7 +454,7 @@ function $UrlMatcherFactory() {
454454 }
455455 }
456456
457- var $types , enqueue = true , typeQueue = [ ] , injector , defaultTypes = {
457+ var $types = { } , enqueue = true , typeQueue = [ ] , injector , defaultTypes = {
458458 "searchParam" : {
459459 encode : normalizeStringOrArray ,
460460 decode : normalizeStringOrArray ,
@@ -610,8 +610,11 @@ function $UrlMatcherFactory() {
610610 * generate URLs with typed parameters.
611611 *
612612 * @param {string } name The type name.
613- * @param {Object|Function } def The type definition. See
613+ * @param {Object|Function } definition The type definition. See
614614 * {@link ui.router.util.type:Type `Type`} for information on the values accepted.
615+ * @param {Object|Function } definitionFn (optional) A function that is injected before the app
616+ * runtime starts. The result of this function is merged into the existing `definition`.
617+ * See {@link ui.router.util.type:Type `Type`} for information on the values accepted.
615618 *
616619 * @returns {Object } Returns `$urlMatcherFactoryProvider`.
617620 *
@@ -659,7 +662,7 @@ function $UrlMatcherFactory() {
659662 * // Defines a custom type that gets a value from a service,
660663 * // where each service gets different types of values from
661664 * // a backend API:
662- * $urlMatcherFactoryProvider.type('dbObject', function(Users, Posts) {
665+ * $urlMatcherFactoryProvider.type('dbObject', {}, function(Users, Posts) {
663666 *
664667 * // Matches up services to URL parameter names
665668 * var services = {
@@ -704,21 +707,35 @@ function $UrlMatcherFactory() {
704707 * });
705708 * </pre>
706709 */
707- this . type = function ( name , def ) {
708- if ( ! isDefined ( def ) ) {
709- if ( ! isDefined ( $types ) ) throw new Error ( "Please wait until runtime to retrieve types." ) ;
710- return $types [ name ] ;
710+ this . type = function ( name , definition , definitionFn ) {
711+ if ( ! isDefined ( definition ) ) return $types [ name ] ;
712+ if ( $types . hasOwnProperty ( name ) ) throw new Error ( "A type named '" + name + "' has already been defined." ) ;
713+
714+ $types [ name ] = new Type ( definition ) ;
715+ if ( definitionFn ) {
716+ typeQueue . push ( { name : name , def : definitionFn } ) ;
717+ if ( ! enqueue ) flushTypeQueue ( ) ;
711718 }
712- typeQueue . push ( { name : name , def : def } ) ;
713- if ( ! enqueue ) flushTypeQueue ( ) ;
714719 return this ;
715720 } ;
716721
722+ // `flushTypeQueue()` waits until `$urlMatcherFactory` is injected before invoking the queued `definitionFn`s
723+ function flushTypeQueue ( ) {
724+ while ( typeQueue . length ) {
725+ var type = typeQueue . shift ( ) ;
726+ if ( type . pattern ) throw new Error ( "You cannot override a type's .pattern at runtime." ) ;
727+ angular . extend ( $types [ type . name ] , injector . invoke ( type . def ) ) ;
728+ }
729+ }
730+
731+ // Register default types. Store them in the prototype of $types.
732+ forEach ( defaultTypes , function ( type , name ) { $types [ name ] = new Type ( type ) ; } ) ;
733+ $types = inherit ( $types , { } ) ;
734+
717735 /* No need to document $get, since it returns this */
718736 this . $get = [ '$injector' , function ( $injector ) {
719737 injector = $injector ;
720738 enqueue = false ;
721- $types = { } ;
722739 flushTypeQueue ( ) ;
723740
724741 forEach ( defaultTypes , function ( type , name ) {
@@ -727,19 +744,6 @@ function $UrlMatcherFactory() {
727744 return this ;
728745 } ] ;
729746
730- // To ensure proper order of operations in object configuration, and to allow internal
731- // types to be overridden, `flushTypeQueue()` waits until `$urlMatcherFactory` is injected
732- // before actually wiring up and assigning type definitions
733- function flushTypeQueue ( ) {
734- forEach ( typeQueue , function ( type ) {
735- if ( $types [ type . name ] ) {
736- throw new Error ( "A type named '" + type . name + "' has already been defined." ) ;
737- }
738- var def = new Type ( isInjectable ( type . def ) ? injector . invoke ( type . def ) : type . def ) ;
739- $types [ type . name ] = def ;
740- } ) ;
741- }
742-
743747 this . Param = function Param ( id , type , config ) {
744748 var self = this ;
745749 var defaultValueConfig = getDefaultValueConfig ( config ) ;
0 commit comments