Skip to content

Commit dc5f71b

Browse files
authored
Merge pull request #91 from xunra/master
Fix wildcards and alwaysSetPrefix when changing languages
2 parents d04cfe6 + 45f5c7b commit dc5f71b

File tree

2 files changed

+49
-17
lines changed

2 files changed

+49
-17
lines changed

src/localize-router.service.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { Injectable } from '@angular/core';
2-
import { Router, NavigationStart, ActivatedRouteSnapshot, NavigationExtras, Route } from '@angular/router';
2+
import { Router, NavigationStart, ActivatedRouteSnapshot, NavigationExtras, Route, UrlSegment } from '@angular/router';
33
import { Subject } from 'rxjs/Subject';
44
import { Observable } from 'rxjs/Observable';
55
import 'rxjs/add/observable/forkJoin';
66
import 'rxjs/add/operator/toPromise';
77

88
import { LocalizeParser } from './localize-router.parser';
9+
import { LocalizeRouterSettings } from './localize-router.config';
910

1011
/**
1112
* Localization service
@@ -20,7 +21,7 @@ export class LocalizeRouterService {
2021
* @param parser
2122
* @param router
2223
*/
23-
constructor(public parser: LocalizeParser, private router: Router) {
24+
constructor(public parser: LocalizeParser, public settings: LocalizeRouterSettings, private router: Router) {
2425
this.routerEvents = new Subject<string>();
2526
}
2627

@@ -43,7 +44,28 @@ export class LocalizeRouterService {
4344
let rootSnapshot: ActivatedRouteSnapshot = this.router.routerState.snapshot.root;
4445

4546
this.parser.translateRoutes(lang).subscribe(() => {
46-
const url = this.traverseRouteSnapshot(rootSnapshot);
47+
let url = this.traverseRouteSnapshot(rootSnapshot);
48+
49+
if (!this.settings.alwaysSetPrefix) {
50+
let urlSegments = url.split('/');
51+
const languageSegmentIndex = urlSegments.indexOf(this.parser.currentLang);
52+
//If the default language has no prefix make sure to remove and add it when necessary
53+
if (this.parser.currentLang === this.parser.defaultLang) {
54+
//Remove the language prefix from url when current language is the default language
55+
if (languageSegmentIndex === 0 || (languageSegmentIndex === 1 && urlSegments[0] === '')) {
56+
//Remove the current aka default language prefix from the url
57+
urlSegments = urlSegments.slice(0, languageSegmentIndex).concat(urlSegments.slice(languageSegmentIndex + 1));
58+
}
59+
} else {
60+
//When coming from a default language it's possible that the url doesn't contain the language, make sure it does.
61+
if (languageSegmentIndex === -1) {
62+
//If the url starts with a slash make sure to keep it.
63+
const injectionIndex = urlSegments[0] === '' ? 1 : 0;
64+
urlSegments = urlSegments.slice(0, injectionIndex).concat(this.parser.currentLang, urlSegments.slice(injectionIndex));
65+
}
66+
}
67+
url = urlSegments.join('/');
68+
}
4769

4870
if (useNavigateMethod) {
4971
this.router.navigate([url], extras);
@@ -61,7 +83,11 @@ export class LocalizeRouterService {
6183
*/
6284
private traverseRouteSnapshot(snapshot: ActivatedRouteSnapshot): string {
6385
if (snapshot.firstChild && snapshot.firstChild.routeConfig && snapshot.firstChild.routeConfig.path) {
64-
return this.parseSegmentValue(snapshot) + '/' + this.traverseRouteSnapshot(snapshot.firstChild);
86+
if (snapshot.firstChild.routeConfig.path !== '**') {
87+
return this.parseSegmentValue(snapshot) + '/' + this.traverseRouteSnapshot(snapshot.firstChild);
88+
} else {
89+
return this.parseSegmentValue(snapshot.firstChild);
90+
}
6591
}
6692
return this.parseSegmentValue(snapshot);
6793
}
@@ -73,8 +99,12 @@ export class LocalizeRouterService {
7399
*/
74100
private parseSegmentValue(snapshot: ActivatedRouteSnapshot): string {
75101
if (snapshot.routeConfig) {
76-
let subPathSegments = snapshot.routeConfig.path.split('/');
77-
return subPathSegments.map((s: string, i: number) => s.indexOf(':') === 0 ? snapshot.url[i].path : s).join('/');
102+
if (snapshot.routeConfig.path === '**') {
103+
return snapshot.url.filter((segment: UrlSegment) => segment.path).map((segment: UrlSegment) => segment.path).join('/');
104+
} else {
105+
let subPathSegments = snapshot.routeConfig.path.split('/');
106+
return subPathSegments.map((s: string, i: number) => s.indexOf(':') === 0 ? snapshot.url[i].path : s).join('/');
107+
}
78108
}
79109
return '';
80110
}

tests/localize-router.service.spec.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Injector } from '@angular/core';
22
import { LocalizeRouterService } from '../src/localize-router.service';
33
import { LocalizeParser } from '../src/localize-router.parser';
4+
import { LocalizeRouterSettings } from '../src/localize-router.config';
45
import { LocalizeRouterModule } from '../src/localize-router.module';
56
import { getTestBed, TestBed, fakeAsync, tick } from '@angular/core/testing';
67
import { Routes, Router, Event, NavigationStart, NavigationEnd } from '@angular/router';
@@ -50,6 +51,7 @@ describe('LocalizeRouterService', () => {
5051
let injector: Injector;
5152
let parser: LocalizeParser;
5253
let router: Router;
54+
let settings: LocalizeRouterSettings;
5355
let localizeRouterService: LocalizeRouterService;
5456
let routes: Routes;
5557

@@ -79,13 +81,13 @@ describe('LocalizeRouterService', () => {
7981

8082
it('is defined', () => {
8183
expect(LocalizeRouterService).toBeDefined();
82-
localizeRouterService = new LocalizeRouterService(parser, router);
84+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
8385
expect(localizeRouterService).toBeDefined();
8486
expect(localizeRouterService instanceof LocalizeRouterService).toBeTruthy();
8587
});
8688

8789
it('should initialize routerEvents', () => {
88-
localizeRouterService = new LocalizeRouterService(parser, router);
90+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
8991
expect(localizeRouterService.routerEvents).toBeDefined();
9092
});
9193

@@ -94,13 +96,13 @@ describe('LocalizeRouterService', () => {
9496
parser.routes = routes;
9597
spyOn(router, 'resetConfig').and.callThrough();
9698

97-
localizeRouterService = new LocalizeRouterService(parser, router);
99+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
98100
localizeRouterService.init();
99101
expect(router.resetConfig).toHaveBeenCalledWith(routes);
100102
});
101103

102104
it('should call parser translateRoute', () => {
103-
localizeRouterService = new LocalizeRouterService(parser, router);
105+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
104106
let testString = 'result/path';
105107
spyOn(parser, 'translateRoute').and.returnValue(testString);
106108

@@ -110,7 +112,7 @@ describe('LocalizeRouterService', () => {
110112
});
111113

112114
it('should append language if root route', () => {
113-
localizeRouterService = new LocalizeRouterService(parser, router);
115+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
114116
parser.currentLang = 'de';
115117
parser.locales = ['de', 'en'];
116118
let testString = '/my/path';
@@ -122,7 +124,7 @@ describe('LocalizeRouterService', () => {
122124
});
123125

124126
it('should translate complex route', () => {
125-
localizeRouterService = new LocalizeRouterService(parser, router);
127+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
126128
parser.currentLang = 'de';
127129
parser.locales = ['de', 'en'];
128130
spyOn(parser, 'translateRoute').and.callFake((val: any) => val);
@@ -135,7 +137,7 @@ describe('LocalizeRouterService', () => {
135137
});
136138

137139
it('should translate routes if language had changed on route event', () => {
138-
localizeRouterService = new LocalizeRouterService(parser, router);
140+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
139141
localizeRouterService.init();
140142
parser.currentLang = 'de';
141143
parser.locales = ['de', 'en'];
@@ -146,7 +148,7 @@ describe('LocalizeRouterService', () => {
146148
});
147149

148150
it('should not translate routes if language not found', () => {
149-
localizeRouterService = new LocalizeRouterService(parser, router);
151+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
150152
parser.currentLang = 'de';
151153
parser.locales = ['de', 'en'];
152154
spyOn(parser, 'translateRoutes').and.stub();
@@ -156,7 +158,7 @@ describe('LocalizeRouterService', () => {
156158
});
157159

158160
it('should not translate routes if language is same', () => {
159-
localizeRouterService = new LocalizeRouterService(parser, router);
161+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
160162
parser.currentLang = 'de';
161163
parser.locales = ['de', 'en'];
162164
spyOn(parser, 'translateRoutes').and.stub();
@@ -166,7 +168,7 @@ describe('LocalizeRouterService', () => {
166168
});
167169

168170
it('should not translate routes if not NavigationStart', () => {
169-
localizeRouterService = new LocalizeRouterService(parser, router);
171+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
170172
parser.currentLang = 'de';
171173
parser.locales = ['de', 'en'];
172174
spyOn(parser, 'translateRoutes').and.stub();
@@ -176,7 +178,7 @@ describe('LocalizeRouterService', () => {
176178
});
177179

178180
it('should not set new url if same language', fakeAsync(() => {
179-
localizeRouterService = new LocalizeRouterService(parser, router);
181+
localizeRouterService = new LocalizeRouterService(parser, settings, router);
180182
parser.currentLang = 'de';
181183
parser.locales = ['de', 'en'];
182184
parser.routes = routes;

0 commit comments

Comments
 (0)