2222$StateProvider . $inject = [ '$urlRouterProvider' , '$urlMatcherFactoryProvider' ] ;
2323function $StateProvider ( $urlRouterProvider , $urlMatcherFactory ) {
2424
25- var root , states = { } , $state , queue = { } , abstractKey = 'abstract' ;
25+ var root , states = { } , $state , queue = { } , abstractKey = 'abstract' , isRuntime = false ;
2626
2727 // Builds state properties from definition passed to registerState()
2828 var stateBuilder = {
@@ -64,12 +64,19 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
6464 return state . url ? state : ( state . parent ? state . parent . navigable : null ) ;
6565 } ,
6666
67+ // Own parameters for this state. state.url.params is already built at this point. Create and add non-url params
68+ ownParams : function ( state ) {
69+ var params = state . url && state . url . params || new $$UMFP . ParamSet ( ) ;
70+ forEach ( state . params || { } , function ( config , id ) {
71+ if ( ! params [ id ] ) params [ id ] = new $$UMFP . Param ( id , null , config ) ;
72+ } ) ;
73+ return params ;
74+ } ,
75+
6776 // Derive parameters for this state and ensure they're a super-set of parent's parameters
6877 params : function ( state ) {
69- if ( ! state . params ) {
70- return state . url ? state . url . params : state . parent . params ;
71- }
72- return state . params ;
78+ var parentParams = state . parent && state . parent . params || new $$UMFP . ParamSet ( ) ;
79+ return inherit ( parentParams , state . ownParams ) ;
7380 } ,
7481
7582 // If there is no explicit multi-view configuration, make one up so we don't have
@@ -87,28 +94,6 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
8794 return views ;
8895 } ,
8996
90- ownParams : function ( state ) {
91- state . params = state . params || { } ;
92-
93- if ( ! state . parent ) {
94- return objectKeys ( state . params ) ;
95- }
96- var paramNames = { } ; forEach ( state . params , function ( v , k ) { paramNames [ k ] = true ; } ) ;
97-
98- forEach ( state . parent . params , function ( v , k ) {
99- if ( ! paramNames [ k ] ) {
100- throw new Error ( "Missing required parameter '" + k + "' in state '" + state . name + "'" ) ;
101- }
102- paramNames [ k ] = false ;
103- } ) ;
104- var ownParams = [ ] ;
105-
106- forEach ( paramNames , function ( own , p ) {
107- if ( own ) ownParams . push ( p ) ;
108- } ) ;
109- return ownParams ;
110- } ,
111-
11297 // Keep a full path from the root down to this state as this is needed for state activation.
11398 path : function ( state ) {
11499 return state . parent ? state . parent . path . concat ( state ) : [ ] ; // exclude root from path
@@ -171,6 +156,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
171156 queue [ parentName ] . push ( state ) ;
172157 }
173158
159+ function flushQueuedChildren ( parentName ) {
160+ var queued = queue [ parentName ] || [ ] ;
161+ while ( queued . length ) {
162+ registerState ( queued . shift ( ) ) ;
163+ }
164+ }
165+
174166 function registerState ( state ) {
175167 // Wrap a new object around the state so we can store our private details easily.
176168 state = inherit ( state , {
@@ -186,10 +178,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
186178 // Get parent name
187179 var parentName = ( name . indexOf ( '.' ) !== - 1 ) ? name . substring ( 0 , name . lastIndexOf ( '.' ) )
188180 : ( isString ( state . parent ) ) ? state . parent
181+ : ( isObject ( state . parent ) && isString ( state . parent . name ) ) ? state . parent . name
189182 : '' ;
190183
191184 // If parent is not registered yet, add state to queue and register later
192- if ( parentName && ! states [ parentName ] ) {
185+ if ( name !== "" && ( ! isRuntime || ! states [ parentName ] ) ) {
193186 return queueState ( parentName , state . self ) ;
194187 }
195188
@@ -208,11 +201,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
208201 }
209202
210203 // Register any queued children
211- if ( queue [ name ] ) {
212- for ( var i = 0 ; i < queue [ name ] . length ; i ++ ) {
213- registerState ( queue [ name ] [ i ] ) ;
214- }
215- }
204+ flushQueuedChildren ( name ) ;
216205
217206 return state ;
218207 }
@@ -538,8 +527,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
538527 * you're coming from.
539528 */
540529 this . $get = $get ;
541- $get . $inject = [ '$rootScope' , '$q' , '$view' , '$injector' , '$resolve' , '$stateParams' , '$urlRouter' ] ;
542- function $get ( $rootScope , $q , $view , $injector , $resolve , $stateParams , $urlRouter ) {
530+ $get . $inject = [ '$rootScope' , '$q' , '$view' , '$injector' , '$resolve' , '$stateParams' , '$urlRouter' , '$location' , '$urlMatcherFactory' ] ;
531+ function $get ( $rootScope , $q , $view , $injector , $resolve , $stateParams , $urlRouter , $location , $urlMatcherFactory ) {
543532
544533 var TransitionSuperseded = $q . reject ( new Error ( 'transition superseded' ) ) ;
545534 var TransitionPrevented = $q . reject ( new Error ( 'transition prevented' ) ) ;
@@ -793,6 +782,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
793782 }
794783 if ( toState [ abstractKey ] ) throw new Error ( "Cannot transition to abstract state '" + to + "'" ) ;
795784 if ( options . inherit ) toParams = inheritParams ( $stateParams , toParams || { } , $state . $current , toState ) ;
785+ if ( ! toState . params . $$validates ( toParams ) ) return TransitionFailed ;
786+
787+ toParams = toState . params . $$values ( toParams ) ;
796788 to = toState ;
797789
798790 var toPath = to . path ;
@@ -801,7 +793,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
801793 var keep = 0 , state = toPath [ keep ] , locals = root . locals , toLocals = [ ] ;
802794
803795 if ( ! options . reload ) {
804- while ( state && state === fromPath [ keep ] && equalForKeys ( toParams , fromParams , state . ownParams ) ) {
796+ while ( state && state === fromPath [ keep ] && state . ownParams . $$equals ( toParams , fromParams ) ) {
805797 locals = toLocals [ keep ] = state . locals ;
806798 keep ++ ;
807799 state = toPath [ keep ] ;
@@ -820,7 +812,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
820812 }
821813
822814 // Filter parameters before we pass them to event handlers etc.
823- toParams = filterByKeys ( objectKeys ( to . params ) , toParams || { } ) ;
815+ toParams = filterByKeys ( to . params . $$keys ( ) , toParams || { } ) ;
824816
825817 // Broadcast start event and cancel the transition if requested
826818 if ( options . notify ) {
@@ -1133,7 +1125,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
11331125 if ( ! nav || nav . url === undefined || nav . url === null ) {
11341126 return null ;
11351127 }
1136- return $urlRouter . href ( nav . url , filterByKeys ( objectKeys ( state . params ) , params || { } ) , {
1128+ return $urlRouter . href ( nav . url , filterByKeys ( state . params . $$keys ( ) , params || { } ) , {
11371129 absolute : options . absolute
11381130 } ) ;
11391131 } ;
@@ -1162,7 +1154,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
11621154 // necessary. In addition to being available to the controller and onEnter/onExit callbacks,
11631155 // we also need $stateParams to be available for any $injector calls we make during the
11641156 // dependency resolution process.
1165- var $stateParams = ( paramsAreFiltered ) ? params : filterByKeys ( objectKeys ( state . params ) , params ) ;
1157+ var $stateParams = ( paramsAreFiltered ) ? params : filterByKeys ( state . params . $$keys ( ) , params ) ;
11661158 var locals = { $stateParams : $stateParams } ;
11671159
11681160 // Resolve 'global' dependencies for the state, i.e. those not specific to a view.
@@ -1203,6 +1195,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
12031195 } ) ;
12041196 }
12051197
1198+ isRuntime = true ;
1199+ flushQueuedChildren ( "" ) ;
1200+
12061201 return $state ;
12071202 }
12081203
0 commit comments