Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bundles/angular2-translator.js

Large diffs are not rendered by default.

29 changes: 22 additions & 7 deletions src/TranslateConfig.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
import {TranslateLoader} from "./TranslateLoader";
import {TranslateLoaderJson} from "./TranslateLoaderJson";

import {Type} from "@angular/core";

export class TranslateConfig {
public static navigator: any = window && window.navigator ? window.navigator : {};

public defaultLang: string;
public providedLangs: string[];
public detectLanguageOnStart: boolean;
public loader: Type<TranslateLoader>;
public loaderConfig: Object;

public navigatorLanguages: string[];

constructor({
defaultLang = "en",
providedLangs = ["en"],
detectLanguageOnStart = true,
}: {
loader = TranslateLoaderJson,
loaderConfig = {},
}: {
defaultLang?: string,
providedLangs?: string[]
detectLanguageOnStart?: boolean
providedLangs?: string[],
detectLanguageOnStart?: boolean,
loader?: Type<TranslateLoader>,
loaderConfig?: Object
}) {
this.defaultLang = providedLangs.indexOf(defaultLang) > -1 ? defaultLang : providedLangs[0];
this.defaultLang = providedLangs.indexOf(defaultLang) > -1 ? defaultLang : providedLangs[0];
this.providedLangs = providedLangs;
this.detectLanguageOnStart = detectLanguageOnStart;
this.loader = loader;
this.loaderConfig = loaderConfig;

this.navigatorLanguages = ((): string[] => {
let navigator: any = TranslateConfig.navigator;

Expand Down Expand Up @@ -60,8 +75,8 @@ export class TranslateConfig {
return languageString.replace(
regExp,
function (substring: string, language: string, country: string = "") {
language = language.toLowerCase();
country = country.toUpperCase();
language = language.toLowerCase();
country = country.toUpperCase();
return country ? language + "-" + country : language;
}
);
Expand All @@ -79,7 +94,7 @@ export class TranslateConfig {
provided = this.providedLangs[p];
} else if (!strict) {
lang = lang.substr(0, 2);
p = providedLangsNormalized.indexOf(lang);
p = providedLangsNormalized.indexOf(lang);
if (p > -1) {
provided = this.providedLangs[p];
} else {
Expand Down
12 changes: 3 additions & 9 deletions src/TranslateLoader.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
/**
* A TranslateLoader has to load every file even if they are divided to partials. If a TranslateLoader resolves
* the language is marked as loaded. It will not get loaded again.
*/
export interface ITranslateLoader {
load(lang: string): Promise<Object>;
}

export abstract class TranslateLoader implements ITranslateLoader {
export abstract class TranslateLoader {
public abstract load(lang: string): Promise<Object>;

public configure(config: Object): void {}
}
46 changes: 22 additions & 24 deletions src/TranslateLoaderJson.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
import {TranslateLoader} from "./TranslateLoader";
import {Inject, Injectable} from "@angular/core";
import {Http} from "@angular/http";

export class TranslateLoaderJsonConfig {
public path: string = "assets/i18n/";
public extension: string = ".json";

// @todo maybe we will change it to a destructed parameter like we did for TranslateConfig
constructor(path?: string, extension?: string) {
if (path) {
this.path = path.replace(/\/+$/, "") + "/";
}

if (extension) {
this.extension = extension;
}
}
}
import {Injectable} from "@angular/core";
import {Http} from "@angular/http";

@Injectable()
export class TranslateLoaderJson extends TranslateLoader {
private _http: Http;
private _config: TranslateLoaderJsonConfig;
private options: {
extension: string,
path: string
} = {
extension: ".json",
path: "assets/i18n",
};

constructor(@Inject(Http) http: Http, @Inject(TranslateLoaderJsonConfig) config: TranslateLoaderJsonConfig) {
constructor(private http: Http) {
super();
this._http = http;
this._config = config;
}

public configure(config: any): void {
if (typeof config.extension === "string") {
this.options.extension = config.extension;
}

if (typeof config.path === "string") {
this.options.path = config.path;
}
}

public load(lang: string): Promise<Object> {
return new Promise((resolve, reject) => {
let file = this._config.path + lang + this._config.extension;
this._http.get(file)
let file = this.options.path + "/" + lang + this.options.extension;
this.http.get(file)
.subscribe(
(response) => {
if (response.status === 200) {
Expand Down
50 changes: 26 additions & 24 deletions src/TranslateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,31 @@ import {TranslateConfig} from "./TranslateConfig";
import {TranslateLoader} from "./TranslateLoader";
import {TranslateLogHandler} from "./TranslateLogHandler";

import {Inject, Injectable} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {Observer} from "rxjs/Observer";
import {Injectable, Injector} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {Observer} from "rxjs/Observer";

import "rxjs/add/operator/share";

@Injectable()
export class TranslateService {
public languageChanged: Observable<string>;
public logHandler: TranslateLogHandler;

private _config: TranslateConfig;
private _loader: TranslateLoader;

private loader: TranslateLoader;
private _lang: string;
private _loadedLangs: Object = {};
private _translations: Object = {};
private _languageChangedObserver: Observer<string>;

constructor(@Inject(TranslateConfig) config: TranslateConfig,
@Inject(TranslateLoader) loader: TranslateLoader,
@Inject(TranslateLogHandler) logHandler: TranslateLogHandler) {
this._config = config;
this._loader = loader;
constructor(public logHandler: TranslateLogHandler,
private config: TranslateConfig,
private injector: Injector) {
this.config = config;
this.logHandler = logHandler;

this.loader = injector.get(config.loader);
this.loader.configure(config.loaderConfig);

this._lang = config.defaultLang;

if (config.detectLanguageOnStart) {
Expand All @@ -48,7 +47,7 @@ export class TranslateService {
}

set lang(lang: string) {
let providedLang = this._config.langProvided(lang, true);
let providedLang = this.config.langProvided(lang, true);

if (typeof providedLang === "string") {
this._lang = providedLang;
Expand Down Expand Up @@ -76,15 +75,17 @@ export class TranslateService {
let detected: string|boolean = false;
let i: number;

this.logHandler.debug("Detecting language from " + JSON.stringify(navLangs) + " in strict mode.");
for (i = 0; i < navLangs.length; i++) {
detected = this._config.langProvided(navLangs[i], true);
detected = this.config.langProvided(navLangs[i], true);
if (detected) {
break;
}
}
if (!detected) {
this.logHandler.debug("Detecting language from " + JSON.stringify(navLangs) + " in non-strict mode.");
for (i = 0; i < navLangs.length; i++) {
detected = this._config.langProvided(navLangs[i]);
detected = this.config.langProvided(navLangs[i]);
if (detected) {
break;
}
Expand All @@ -101,9 +102,9 @@ export class TranslateService {
* @returns {Promise<void>|Promise}
*/
public waitForTranslation(lang: string = this._lang): Promise<void> {
let l = this._config.langProvided(lang, true);
let l = this.config.langProvided(lang, true);
if (!l) {
return Promise.reject("Language not provided");
return Promise.reject("Language " + lang + " not provided");
} else {
lang = String(l);
}
Expand All @@ -123,7 +124,7 @@ export class TranslateService {
public translate(keys: string|string[], params: any = {}, lang: string = this._lang): Promise<string|string[]> {
return new Promise<string|string[]>((resolve) => {
if (lang !== this._lang) {
let l = this._config.langProvided(lang, true);
let l = this.config.langProvided(lang, true);
if (!l) {
resolve(keys);
return;
Expand Down Expand Up @@ -156,9 +157,12 @@ export class TranslateService {
}

if (lang !== this._lang) {
let l = this._config.langProvided(lang, true);
let l = this.config.langProvided(lang, true);
if (l) {
lang = String(l);
} else {
this.logHandler.error("Language " + lang + " not provided");
return keys;
}
}

Expand Down Expand Up @@ -205,7 +209,7 @@ export class TranslateService {
private _loadLang(lang: string): Promise<void> {
if (!this._loadedLangs[lang]) {
this._loadedLangs[lang] = new Promise<void>((resolve, reject) => {
this._loader.load(lang).then((translations) => {
this.loader.load(lang).then((translations) => {
this._translations[lang] = translations;
this.logHandler.info("Language " + lang + " got loaded");
resolve();
Expand Down Expand Up @@ -258,16 +262,14 @@ export class TranslateService {
* @returns {string}
* @private
*/
private _referencedError(sub: string, unexpected: string, expected?: string, pos?: number): string {
private _referencedError(sub: string, unexpected: string, expected: string, pos?: number): string {
let msg = "Parse error unexpected " + unexpected;

if (pos !== undefined) {
msg += " at pos " + (pos + 3);
}

if (expected) {
msg += " expected " + expected;
}
msg += " expected " + expected;

this.logHandler.error(msg + " in '" + sub + "'");
return "";
Expand Down
16 changes: 3 additions & 13 deletions src/TranslatorModule.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {TranslateComponent} from "./TranslateComponent";
import {TranslateConfig} from "./TranslateConfig";
import {TranslateLoader} from "./TranslateLoader";
import {TranslateLoaderJson, TranslateLoaderJsonConfig} from "./TranslateLoaderJson";
import {TranslateLoaderJson} from "./TranslateLoaderJson";
import {TranslateLogHandler} from "./TranslateLogHandler";
import {TranslatePipe} from "./TranslatePipe";
import {TranslateService} from "./TranslateService";
Expand All @@ -21,18 +20,9 @@ import {HttpModule} from "@angular/http";
imports: [HttpModule],
providers: [
{ provide: TranslateConfig, useValue: new TranslateConfig({}) },
{ provide: TranslateLoaderJsonConfig, useValue: new TranslateLoaderJsonConfig() },
{ provide: TranslateLoader, useClass: TranslateLoaderJson },
{ provide: TranslateLogHandler, useClass: TranslateLogHandler },
TranslateLoaderJson,
TranslateLogHandler,
TranslateService,
],
})
export class TranslatorModule {}

export const TRANSLATE_PROVIDERS: any[] = [
{ provide: TranslateConfig, useValue: new TranslateConfig({}) },
{ provide: TranslateLoaderJsonConfig, useValue: new TranslateLoaderJsonConfig() },
{ provide: TranslateLoader, useClass: TranslateLoaderJson },
{ provide: TranslateLogHandler, useValue: TranslateLogHandler },
TranslateService,
];
Loading