UNPKG

angular-l10n

Version:

An Angular library to translate messages, dates and numbers

254 lines 9.49 kB
/** * @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