@@ -27,6 +27,10 @@ export class Segment {
2727 regex : string ;
2828}
2929
30+ export class ContinuationSegment extends Segment {
31+ generate ( params ) : string { return '' ; }
32+ }
33+
3034class StaticSegment extends Segment {
3135 regex : string ;
3236 name : string ;
@@ -71,7 +75,7 @@ var wildcardMatcher = RegExpWrapper.create("^\\*([^\/]+)$");
7175function parsePathString ( route : string ) {
7276 // normalize route as not starting with a "/". Recognition will
7377 // also normalize.
74- if ( route [ 0 ] === "/" ) {
78+ if ( StringWrapper . startsWith ( route , "/" ) ) {
7579 route = StringWrapper . substring ( route , 1 ) ;
7680 }
7781
@@ -93,14 +97,21 @@ function parsePathString(route: string) {
9397 throw new BaseException ( `'${ route } ' has more than the maximum supported number of segments.` ) ;
9498 }
9599
96- for ( var i = 0 ; i < segments . length ; i ++ ) {
100+ var limit = segments . length - 1 ;
101+ for ( var i = 0 ; i <= limit ; i ++ ) {
97102 var segment = segments [ i ] , match ;
98103
99104 if ( isPresent ( match = RegExpWrapper . firstMatch ( paramMatcher , segment ) ) ) {
100105 results . push ( new DynamicSegment ( match [ 1 ] ) ) ;
101106 specificity += ( 100 - i ) ;
102107 } else if ( isPresent ( match = RegExpWrapper . firstMatch ( wildcardMatcher , segment ) ) ) {
103108 results . push ( new StarSegment ( match [ 1 ] ) ) ;
109+ } else if ( segment == '...' ) {
110+ if ( i < limit ) {
111+ // TODO (matsko): setup a proper error here `
112+ throw new BaseException ( `Unexpected "..." before the end of the path for "${ route } ".` ) ;
113+ }
114+ results . push ( new ContinuationSegment ( ) ) ;
104115 } else if ( segment . length > 0 ) {
105116 results . push ( new StaticSegment ( segment ) ) ;
106117 specificity += 100 * ( 100 - i ) ;
@@ -120,6 +131,7 @@ export class PathRecognizer {
120131 segments : List < Segment > ;
121132 regex : RegExp ;
122133 specificity : number ;
134+ terminal : boolean = true ;
123135
124136 constructor ( public path : string , public handler : any ) {
125137 this . segments = [ ] ;
@@ -131,7 +143,17 @@ export class PathRecognizer {
131143 var segments = parsed [ 'segments' ] ;
132144 var regexString = '^' ;
133145
134- ListWrapper . forEach ( segments , ( segment ) => { regexString += '/' + segment . regex ; } ) ;
146+ ListWrapper . forEach ( segments , ( segment ) => {
147+ if ( segment instanceof ContinuationSegment ) {
148+ this . terminal = false ;
149+ } else {
150+ regexString += '/' + segment . regex ;
151+ }
152+ } ) ;
153+
154+ if ( this . terminal ) {
155+ regexString += '$' ;
156+ }
135157
136158 this . regex = RegExpWrapper . create ( regexString ) ;
137159 this . segments = segments ;
@@ -143,6 +165,10 @@ export class PathRecognizer {
143165 var urlPart = url ;
144166 for ( var i = 0 ; i < this . segments . length ; i ++ ) {
145167 var segment = this . segments [ i ] ;
168+ if ( segment instanceof ContinuationSegment ) {
169+ continue ;
170+ }
171+
146172 var match = RegExpWrapper . firstMatch ( RegExpWrapper . create ( '/' + segment . regex ) , urlPart ) ;
147173 urlPart = StringWrapper . substring ( urlPart , match [ 0 ] . length ) ;
148174 if ( segment . name . length > 0 ) {
0 commit comments