@@ -5,7 +5,6 @@ import {ListWrapper, Map, MapWrapper, StringMapWrapper} from 'angular2/src/facad
55import { Promise , PromiseWrapper } from 'angular2/src/facade/async' ;
66import {
77 isPresent ,
8- isArray ,
98 isBlank ,
109 isType ,
1110 isString ,
@@ -189,61 +188,70 @@ export class RouteRegistry {
189188 * Given a normalized list with component names and params like: `['user', {id: 3 }]`
190189 * generates a url with a leading slash relative to the provided `parentComponent`.
191190 */
192- generate ( linkParams : any [ ] , parentComponent : any , _aux = false ) : Instruction {
193- let linkIndex = 0 ;
194- let routeName = linkParams [ linkIndex ] ;
195-
196- // TODO: this is kind of odd but it makes existing assertions pass
197- if ( isBlank ( parentComponent ) ) {
198- throw new BaseException ( `Could not find route named "${ routeName } ".` ) ;
199- }
200-
201- if ( ! isString ( routeName ) ) {
202- throw new BaseException ( `Unexpected segment "${ routeName } " in link DSL. Expected a string.` ) ;
203- } else if ( routeName == '' || routeName == '.' || routeName == '..' ) {
204- throw new BaseException ( `"${ routeName } /" is only allowed at the beginning of a link DSL.` ) ;
205- }
191+ generate ( linkParams : any [ ] , parentComponent : any ) : Instruction {
192+ let segments = [ ] ;
193+ let componentCursor = parentComponent ;
194+ var lastInstructionIsTerminal = false ;
195+
196+ for ( let i = 0 ; i < linkParams . length ; i += 1 ) {
197+ let segment = linkParams [ i ] ;
198+ if ( isBlank ( componentCursor ) ) {
199+ throw new BaseException ( `Could not find route named "${ segment } ".` ) ;
200+ }
201+ if ( ! isString ( segment ) ) {
202+ throw new BaseException ( `Unexpected segment "${ segment } " in link DSL. Expected a string.` ) ;
203+ } else if ( segment == '' || segment == '.' || segment == '..' ) {
204+ throw new BaseException ( `"${ segment } /" is only allowed at the beginning of a link DSL.` ) ;
205+ }
206+ let params = { } ;
207+ if ( i + 1 < linkParams . length ) {
208+ let nextSegment = linkParams [ i + 1 ] ;
209+ if ( isStringMap ( nextSegment ) ) {
210+ params = nextSegment ;
211+ i += 1 ;
212+ }
213+ }
206214
207- let params = { } ;
208- if ( linkIndex + 1 < linkParams . length ) {
209- let nextSegment = linkParams [ linkIndex + 1 ] ;
210- if ( isStringMap ( nextSegment ) && ! isArray ( nextSegment ) ) {
211- params = nextSegment ;
212- linkIndex += 1 ;
215+ var componentRecognizer = this . _rules . get ( componentCursor ) ;
216+ if ( isBlank ( componentRecognizer ) ) {
217+ throw new BaseException (
218+ `Component "${ getTypeNameForDebugging ( componentCursor ) } " has no route config.` ) ;
213219 }
214- }
220+ var response = componentRecognizer . generate ( segment , params ) ;
215221
216- let auxInstructions : { [ key : string ] : Instruction } = { } ;
217- var nextSegment ;
218- while ( linkIndex + 1 < linkParams . length && isArray ( nextSegment = linkParams [ linkIndex + 1 ] ) ) {
219- auxInstructions [ nextSegment [ 0 ] ] = this . generate ( nextSegment , parentComponent , true ) ;
220- linkIndex += 1 ;
222+ if ( isBlank ( response ) ) {
223+ throw new BaseException (
224+ `Component "${ getTypeNameForDebugging ( componentCursor ) } " has no route named "${ segment } ".` ) ;
225+ }
226+ segments . push ( response ) ;
227+ componentCursor = response . componentType ;
228+ lastInstructionIsTerminal = response . terminal ;
221229 }
222230
223- var componentRecognizer = this . _rules . get ( parentComponent ) ;
224- if ( isBlank ( componentRecognizer ) ) {
225- throw new BaseException (
226- `Component "${ getTypeNameForDebugging ( parentComponent ) } " has no route config.` ) ;
227- }
231+ var instruction : Instruction = null ;
228232
229- var componentInstruction = _aux ? componentRecognizer . generateAuxiliary ( routeName , params ) :
230- componentRecognizer . generate ( routeName , params ) ;
233+ if ( ! lastInstructionIsTerminal ) {
234+ instruction = this . _generateRedirects ( componentCursor ) ;
231235
232- if ( isBlank ( componentInstruction ) ) {
233- throw new BaseException (
234- `Component "${ getTypeNameForDebugging ( parentComponent ) } " has no route named "${ routeName } ".` ) ;
236+ if ( isPresent ( instruction ) ) {
237+ let lastInstruction = instruction ;
238+ while ( isPresent ( lastInstruction . child ) ) {
239+ lastInstruction = lastInstruction . child ;
240+ }
241+ lastInstructionIsTerminal = lastInstruction . component . terminal ;
242+ }
243+ if ( isPresent ( componentCursor ) && ! lastInstructionIsTerminal ) {
244+ throw new BaseException (
245+ `Link "${ ListWrapper . toJSON ( linkParams ) } " does not resolve to a terminal or async instruction.` ) ;
246+ }
235247 }
236248
237- var childInstruction = null ;
238- if ( linkIndex + 1 < linkParams . length ) {
239- var remaining = linkParams . slice ( linkIndex + 1 ) ;
240- childInstruction = this . generate ( remaining , componentInstruction . componentType ) ;
241- } else if ( ! componentInstruction . terminal ) {
242- throw new BaseException (
243- `Link "${ ListWrapper . toJSON ( linkParams ) } " does not resolve to a terminal or async instruction.` ) ;
249+
250+ while ( segments . length > 0 ) {
251+ instruction = new Instruction ( segments . pop ( ) , instruction , { } ) ;
244252 }
245253
246- return new Instruction ( componentInstruction , childInstruction , auxInstructions ) ;
254+ return instruction ;
247255 }
248256
249257 public hasRoute ( name : string , parentComponent : any ) : boolean {
0 commit comments