angular-l10n
Version:
An Angular library to translate messages, dates and numbers
254 lines • 9.49 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Injectable, Inject } from "@angular/core";
import { Router, NavigationStart, NavigationEnd } from "@angular/router";
import { Location } from "@angular/common";
import { filter } from "rxjs/operators";
import { LocaleService } from "../services/locale.service";
import { InjectorRef } from "./injector-ref";
import { L10N_CONFIG } from "./l10n-config";
import { ISOCode, ExtraCode } from "./types";
export class LocalizedRouting {
/**
* @param {?} configuration
* @param {?} locale
*/
constructor(configuration, locale) {
this.configuration = configuration;
this.locale = locale;
}
/**
* @return {?}
*/
get router() {
return InjectorRef.get(Router);
}
/**
* @return {?}
*/
get location() {
return InjectorRef.get(Location);
}
/**
* @return {?}
*/
init() {
if (this.configuration.localizedRouting.format) {
// Parses the url to find the locale when the app starts.
/** @type {?} */
const path = this.location.path(true);
this.parsePath(path);
// Parses the url to find the locale when a navigation starts.
this.router.events.pipe(filter((event) => event instanceof NavigationStart)).subscribe((data) => {
this.redirectToPath(data.url);
});
// Replaces url when a navigation ends.
this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe((data) => {
/** @type {?} */
const url = (!!data.url && data.url != "/" && data.url == data.urlAfterRedirects) ?
data.url :
data.urlAfterRedirects;
this.replacePath(this.locale.composeLocale((/** @type {?} */ (this.configuration.localizedRouting.format))), url);
});
// Replaces url when locale changes.
this.locale.languageCodeChanged.subscribe(() => {
this.replacePath(this.locale.composeLocale((/** @type {?} */ (this.configuration.localizedRouting.format))));
});
this.locale.defaultLocaleChanged.subscribe(() => {
this.replacePath(this.locale.composeLocale((/** @type {?} */ (this.configuration.localizedRouting.format))));
});
}
}
/**
* Parses path to find the locale.
* @param {?=} path The path to be parsed
* @return {?}
*/
parsePath(path) {
if (!path)
return;
/** @type {?} */
const segment = this.getLocalizedSegment(path);
if (segment != null) {
/** @type {?} */
const locale = (/** @type {?} */ (segment)).replace(/\//gi, "");
/** @type {?} */
const localeCodes = this.splitLocale(locale, (/** @type {?} */ (this.configuration.localizedRouting.format)));
// Unrecognized segment.
if (this.configuration.localizedRouting.schema) {
if (!this.compareLocale(localeCodes, {
languageCode: localeCodes.languageCode,
scriptCode: this.getSchema(ISOCode.Script, localeCodes),
countryCode: this.getSchema(ISOCode.Country, localeCodes)
}))
return;
}
if (this.configuration.locale.language) {
this.locale.setCurrentLanguage(localeCodes.languageCode);
}
if (this.configuration.locale.defaultLocale) {
this.locale.setDefaultLocale(localeCodes.languageCode, localeCodes.countryCode || this.getSchema(ISOCode.Country, localeCodes), localeCodes.scriptCode || this.getSchema(ISOCode.Script, localeCodes), this.getSchema(ExtraCode.NumberingSystem, localeCodes), this.getSchema(ExtraCode.Calendar, localeCodes));
}
if (this.configuration.locale.currency) {
/** @type {?} */
const currency = this.getSchema(ExtraCode.Currency, localeCodes);
if (currency) {
this.locale.setCurrentCurrency(currency);
}
}
if (this.configuration.locale.timezone) {
/** @type {?} */
const timezone = this.getSchema(ExtraCode.Timezone, localeCodes);
if (timezone) {
this.locale.setCurrentTimezone(timezone);
}
}
}
}
/**
* Removes the locale from the path and navigates without pushing a new state into history.
* @param {?} path Localized path
* @return {?}
*/
redirectToPath(path) {
/** @type {?} */
const segment = this.getLocalizedSegment(path);
if (segment != null) {
/** @type {?} */
const url = path.replace(segment, "/");
// navigateByUrl keeps the query params.
this.router.navigateByUrl(url, { skipLocationChange: true });
}
}
/**
* Replaces the path with the locale without pushing a new state into history.
* @param {?} locale The current locale
* @param {?=} path The path to be replaced
* @return {?}
*/
replacePath(locale, path) {
if (path) {
if (!this.isDefaultRouting()) {
this.location.replaceState(this.getLocalizedPath(locale, path));
}
}
else {
path = this.location.path(true);
// Parses the path to find the locale.
/** @type {?} */
const segment = this.getLocalizedSegment(path);
if (segment != null) {
// Removes the locale from the path.
path = path.replace(segment, "/");
if (this.isDefaultRouting()) {
this.location.replaceState(path);
}
}
if (!this.isDefaultRouting()) {
this.location.replaceState(this.getLocalizedPath(locale, path));
}
}
}
/**
* @param {?} path
* @return {?}
*/
getLocalizedSegment(path) {
for (const lang of this.locale.getAvailableLanguages()) {
/** @type {?} */
const regex = new RegExp(`(\/${lang}\/)|(\/${lang}$)|(\/${lang}-.*?\/)|(\/${lang}-.*?$)`);
/** @type {?} */
const segments = path.match(regex);
if (segments != null) {
return segments[0];
}
}
return null;
}
/**
* @param {?} locale
* @param {?} codes
* @return {?}
*/
splitLocale(locale, codes) {
/** @type {?} */
const values = locale.split("-");
/** @type {?} */
const localeCodes = { languageCode: "" };
if (codes.length > 0) {
for (let i = 0; i < codes.length; i++) {
if (values[i])
localeCodes[codes[i]] = values[i];
}
}
return localeCodes;
}
/**
* @param {?} locale1
* @param {?} locale2
* @return {?}
*/
compareLocale(locale1, locale2) {
return locale1.languageCode == locale2.languageCode &&
(!!locale1.scriptCode ?
locale1.scriptCode == locale2.scriptCode : true) &&
(!!locale1.countryCode ?
locale1.countryCode == locale2.countryCode : true);
}
/**
* @param {?} code
* @param {?} locale
* @return {?}
*/
getSchema(code, locale) {
if (!this.configuration.localizedRouting.schema)
return undefined;
/** @type {?} */
const schema = this.configuration.localizedRouting.schema
.find(((s) => this.compareLocale(locale, s)));
return schema ? schema[code] : undefined;
}
/**
* @return {?}
*/
isDefaultRouting() {
if (!this.configuration.localizedRouting.defaultRouting)
return false;
if (this.configuration.locale.language) {
return this.locale.getCurrentLanguage() == this.configuration.locale.language;
}
if (this.configuration.locale.defaultLocale) {
return this.compareLocale({
languageCode: this.locale.getCurrentLanguage(),
scriptCode: this.locale.getCurrentScript(),
countryCode: this.locale.getCurrentCountry()
}, this.configuration.locale.defaultLocale);
}
return false;
}
/**
* @param {?} locale
* @param {?} path
* @return {?}
*/
getLocalizedPath(locale, path) {
return Location.stripTrailingSlash("/" + locale + path);
}
}
LocalizedRouting.decorators = [
{ type: Injectable }
];
/** @nocollapse */
LocalizedRouting.ctorParameters = () => [
{ type: undefined, decorators: [{ type: Inject, args: [L10N_CONFIG,] }] },
{ type: LocaleService }
];
if (false) {
/** @type {?} */
LocalizedRouting.prototype.configuration;
/** @type {?} */
LocalizedRouting.prototype.locale;
}
//# sourceMappingURL=localized-routing.js.map