1- import  { BrowserLocation }  from  './browser_location ' ; 
1+ import  { LocationStrategy }  from  './location_strategy ' ; 
22import  { StringWrapper ,  isPresent ,  CONST_EXPR }  from  'angular2/src/facade/lang' ; 
33import  { EventEmitter ,  ObservableWrapper }  from  'angular2/src/facade/async' ; 
44import  { OpaqueToken ,  Injectable ,  Optional ,  Inject }  from  'angular2/di' ; 
55
66export  const  appBaseHrefToken : OpaqueToken  =  CONST_EXPR ( new  OpaqueToken ( 'locationHrefToken' ) ) ; 
77
8+ /** 
9+  * This is the service that an application developer will directly interact with. 
10+  * 
11+  * Responsible for normalizing the URL against the application's base href. 
12+  * A normalized URL is absolute from the URL host, includes the application's base href, and has no 
13+  * trailing slash: 
14+  * - `/my/app/user/123` is normalized 
15+  * - `my/app/user/123` **is not** normalized 
16+  * - `/my/app/user/123/` **is not** normalized 
17+  */ 
818@Injectable ( ) 
919export  class  Location  { 
1020  private  _subject : EventEmitter ; 
1121  private  _baseHref : string ; 
1222
13-   constructor ( public  _browserLocation :  BrowserLocation , 
23+   constructor ( public  _platformStrategy :  LocationStrategy , 
1424              @Optional ( )  @Inject ( appBaseHrefToken )  href ?: string )  { 
1525    this . _subject  =  new  EventEmitter ( ) ; 
16-     this . _baseHref  =  stripIndexHtml ( isPresent ( href )  ? href  : this . _browserLocation . getBaseHref ( ) ) ; 
17-     this . _browserLocation . onPopState ( ( _ )  =>  this . _onPopState ( _ ) ) ; 
26+     this . _baseHref  =  stripTrailingSlash ( 
27+         stripIndexHtml ( isPresent ( href )  ? href  : this . _platformStrategy . getBaseHref ( ) ) ) ; 
28+     this . _platformStrategy . onPopState ( ( _ )  =>  this . _onPopState ( _ ) ) ; 
1829  } 
1930
2031  _onPopState ( _ ) : void   {  ObservableWrapper . callNext ( this . _subject ,  { 'url' : this . path ( ) } ) ;  } 
2132
22-   path ( ) : string  {  return  this . normalize ( this . _browserLocation . path ( ) ) ;  } 
33+   path ( ) : string  {  return  this . normalize ( this . _platformStrategy . path ( ) ) ;  } 
2334
24-   normalize ( url : string ) : string  {  return  this . _stripBaseHref ( stripIndexHtml ( url ) ) ;  } 
35+   normalize ( url : string ) : string  { 
36+     return  stripTrailingSlash ( this . _stripBaseHref ( stripIndexHtml ( url ) ) ) ; 
37+   } 
2538
2639  normalizeAbsolutely ( url : string ) : string  { 
27-     if  ( url . length   >   0   &&   url [ 0 ]   !=   '/' )  { 
40+     if  ( ! url . startsWith ( '/' ) )  { 
2841      url  =  '/'  +  url ; 
2942    } 
30-     return  this . _addBaseHref ( url ) ; 
43+     return  stripTrailingSlash ( this . _addBaseHref ( url ) ) ; 
3144  } 
3245
3346  _stripBaseHref ( url : string ) : string  { 
34-     if  ( this . _baseHref . length  >  0  &&  StringWrapper . startsWith ( url ,   this . _baseHref ) )  { 
35-       return  StringWrapper . substring ( url ,   this . _baseHref . length ) ; 
47+     if  ( this . _baseHref . length  >  0  &&  url . startsWith ( this . _baseHref ) )  { 
48+       return  url . substring ( this . _baseHref . length ) ; 
3649    } 
3750    return  url ; 
3851  } 
3952
4053  _addBaseHref ( url : string ) : string  { 
41-     if  ( ! StringWrapper . startsWith ( url ,   this . _baseHref ) )  { 
54+     if  ( ! url . startsWith ( this . _baseHref ) )  { 
4255      return  this . _baseHref  +  url ; 
4356    } 
4457    return  url ; 
4558  } 
4659
4760  go ( url : string ) : void   { 
4861    var  finalUrl  =  this . normalizeAbsolutely ( url ) ; 
49-     this . _browserLocation . pushState ( null ,  '' ,  finalUrl ) ; 
62+     this . _platformStrategy . pushState ( null ,  '' ,  finalUrl ) ; 
5063  } 
5164
52-   forward ( ) : void   {  this . _browserLocation . forward ( ) ;  } 
65+   forward ( ) : void   {  this . _platformStrategy . forward ( ) ;  } 
5366
54-   back ( ) : void   {  this . _browserLocation . back ( ) ;  } 
67+   back ( ) : void   {  this . _platformStrategy . back ( ) ;  } 
5568
5669  subscribe ( onNext ,  onThrow  =  null ,  onReturn  =  null ) : void   { 
5770    ObservableWrapper . subscribe ( this . _subject ,  onNext ,  onThrow ,  onReturn ) ; 
@@ -61,12 +74,16 @@ export class Location {
6174
6275
6376function  stripIndexHtml ( url : string ) : string  { 
64-   // '/ index.html'.length == 11 
65-   if   ( url . length   >   10   &&   StringWrapper . substring ( url ,   url . length   -   11 )   ==   '/index.html' )   { 
66-     return  StringWrapper . substring ( url ,   0 ,  url . length  -  11 ) ; 
77+   if   ( / \/ i n d e x .h t m l $ / g . test ( url ) )   { 
78+      //  '/index.html'.length == 11 
79+     return  url . substring ( 0 ,  url . length  -  11 ) ; 
6780  } 
68-   if  ( url . length  >  1  &&  url [ url . length  -  1 ]  ==  '/' )  { 
69-     url  =  StringWrapper . substring ( url ,  0 ,  url . length  -  1 ) ; 
81+   return  url ; 
82+ } 
83+ 
84+ function  stripTrailingSlash ( url : string ) : string  { 
85+   if  ( / \/ $ / g. test ( url ) )  { 
86+     url  =  url . substring ( 0 ,  url . length  -  1 ) ; 
7087  } 
7188  return  url ; 
7289} 
0 commit comments