diff --git a/.gitignore b/.gitignore index 63f7beec..65f1f225 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ $ cat .gitignore /node_modules -/dist \ No newline at end of file +/bundles + +# Ignored files +*.js +*.map +*.d.ts \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..30bc1627 --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +/node_modules \ No newline at end of file diff --git a/AdvancedUse.jpg b/AdvancedUse.jpg deleted file mode 100644 index 13f13dcf..00000000 Binary files a/AdvancedUse.jpg and /dev/null differ diff --git a/README.md b/README.md index 1a7304cc..10654b6c 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,68 @@ # Angular 2 Localization -> A translation service for the new Angular 2 applications using TypeScript. -> Simple & fast. +> An Angular 2 library for i18n and l10n that implements a translation service - using TypeScript and SystemJS. -## Sample application +## Sample app Sample application that implements the translation service: [demo](http://robisim74.github.io/angular2localization) +## Installation +You can add `angular2localization` to your project via [Node and npm](https://nodejs.org): +``` +npm install --save angular2localization +``` +To load the package you have two methods: +- Loading the bundle: +```Html + + +``` +- Using SystemJS: +```Html + + +``` + ## Getting the translation To get the translation, add in the template: -``` +```Html {{ 'TITLE' | translate }} ``` - -### Translating with i18n -With `I18n Select` that displays the string that matches the current value: +and in each component: +```TypeScript +@Component({ + ... + pipes: [TranslatePipe] +}) ``` +With `I18n Select` that displays the string that matches the current value: +```Html {{ gender | i18nSelect: inviteMapping | translate }} ``` With `I18n Plural` that pluralizes the value properly: -``` +```Html {{ messages.length | i18nPlural: messageMapping | translate }} ``` -## How to use the translation service -Include in your application: -* the `locale` and `localization` services; -* the `localization` pipe; - -and register `LocaleService`, `LocalizationService` and `LocalizationPipe` in the route component: +## Basic usage +Add in the route component in order to access the data of location from anywhere in the application: ```TypeScript // Services. -import {LocaleService} from './services/locale.service'; // LocaleService class. -import {LocalizationService} from './services/localization.service'; // LocalizationService class. +import {LocaleService} from 'angular2localization/angular2localization'; // LocaleService class. +import {LocalizationService} from 'angular2localization/angular2localization'; // LocalizationService class. // Pipes. -import {LocalizationPipe} from './pipes/localization.pipe'; // LocalizationPipe class. +import {TranslatePipe} from 'angular2localization/angular2localization'; // TranslatePipe class. @Component({ selector: 'app-component', ... - providers: [LocaleService, LocalizationService, LocalizationPipe], // Localization providers: inherited by all descendants. - pipes: [LocalizationPipe] // Add in each component to invoke the transform method. + providers: [LocaleService, LocalizationService, TranslatePipe], // Localization providers: inherited by all descendants. + pipes: [TranslatePipe] // Add in each component to invoke the transform method. }) export class AppComponent { @@ -64,7 +88,7 @@ bootstrap(AppComponent, [HTTP_PROVIDERS]); To initialize the `LocalizationService` for the direct loading, add the following code in the body of the constructor of the route component: ```TypeScript var translationEN = { - TITLE: 'ANGULAR 2 LOCALIZATION', + TITLE: 'angular 2 localization', CHANGE_LANGUAGE: 'change language', ... } @@ -80,7 +104,7 @@ To initialize the `LocalizationService` for the asynchronous loading add the fol ```TypeScript this.localization.translationProvider('./resources/locale-'); // Required: initializes the translation provider with the given path prefix. ``` -and create the json files of the translations such as `locale-en.json`: +and create the `json` files of the translations such as `locale-en.json`: ``` { "TITLE": "angular 2 localization", @@ -99,24 +123,23 @@ Because strings must be written within quotes, use the `\` escape character to i "\"What's happened to me?\" he thought." ``` -## Changing language +### Changing language To change language at runtime, add in the route component: ```TypeScript -selectLanguage(language) { +selectLanguage(language: string) { this.locale.setCurrentLanguage(language); } ``` where `language` is the two-letter code of the language; then add in the view: -``` +```Html English ... ``` ## Advanced use with AsyncRoute -If you use an `AsyncRoute` in an extended application, you can create an instance of the `LocalizationService` for every asynchronously loaded component, as shown: -![AdvancedUse](https://github.com/robisim74/angular2localization/blob/master/AdvancedUse.jpg) +If you use an `AsyncRoute` in an extended application, you can create an instance of the `LocalizationService` for every asynchronously loaded component. Each instance is different, and can be directly or asynchronously loaded, as in this example: ```TypeScript export class I18nComponent { @@ -130,21 +153,7 @@ export class I18nComponent { } ``` -In this way, application performance and memory usage are optimized. +In this way, application performance and memory usage are optimized. See the [demo](http://robisim74.github.io/angular2localization) for a sample code. -## Running the sample app -What you need to run the sample app: -- this repository -- [Node and npm](https://nodejs.org) already installed. - -In the command line, go to the directory that contains `index.html`: -``` -npm install -gulp -``` -You need a static server as [lite-server](https://github.com/johnpapa/lite-server): -``` -npm install -g lite-server -lite-server -``` -and then in a browser visit `localhost:3000/index.html`. \ No newline at end of file +##License +MIT \ No newline at end of file diff --git a/angular2localization.ts b/angular2localization.ts new file mode 100644 index 00000000..6d5ef86d --- /dev/null +++ b/angular2localization.ts @@ -0,0 +1,4 @@ +// Exports services & pipes. +export * from './src/services/localization.service'; +export * from './src/services/locale.service'; +export * from './src/pipes/translate.pipe'; \ No newline at end of file diff --git a/app/app.component.html b/app/app.component.html deleted file mode 100644 index bfe1bd20..00000000 --- a/app/app.component.html +++ /dev/null @@ -1,45 +0,0 @@ - - -
- - - -
- -
- - - - -
\ No newline at end of file diff --git a/app/app.component.js b/app/app.component.js deleted file mode 100644 index 8436d0be..00000000 --- a/app/app.component.js +++ /dev/null @@ -1,84 +0,0 @@ -System.register(['angular2/core', 'angular2/common', 'angular2/router', './services/locale.service', './services/localization.service', './pipes/localization.pipe', './home.component', './i18n.component'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1, common_1, router_1, locale_service_1, localization_service_1, localization_pipe_1, home_component_1, i18n_component_1; - var AppComponent; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }, - function (common_1_1) { - common_1 = common_1_1; - }, - function (router_1_1) { - router_1 = router_1_1; - }, - function (locale_service_1_1) { - locale_service_1 = locale_service_1_1; - }, - function (localization_service_1_1) { - localization_service_1 = localization_service_1_1; - }, - function (localization_pipe_1_1) { - localization_pipe_1 = localization_pipe_1_1; - }, - function (home_component_1_1) { - home_component_1 = home_component_1_1; - }, - function (i18n_component_1_1) { - i18n_component_1 = i18n_component_1_1; - }], - execute: function() { - AppComponent = (function () { - function AppComponent(locale, localization, location) { - this.locale = locale; - this.localization = localization; - this.location = location; - // Initializes the LocaleService & LocalizationService: asynchronous loading. - this.locale.addLanguage('en'); // Required: adds a new language. - this.locale.addLanguage('it'); - this.locale.definePreferredLanguage('en', 30); // Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie. - this.localization.translationProvider('./resources/locale-'); // Required: initializes the translation provider with the given path prefix. - } - Object.defineProperty(AppComponent.prototype, "currentLanguage", { - // Gets the current language. - get: function () { - return this.locale.getCurrentLanguage(); - }, - enumerable: true, - configurable: true - }); - // Sets a new language. - AppComponent.prototype.selectLanguage = function (language) { - this.locale.setCurrentLanguage(language); - }; - AppComponent = __decorate([ - core_1.Component({ - selector: 'app-component', - directives: [router_1.ROUTER_DIRECTIVES, common_1.NgClass], - templateUrl: './app/app.component.html', - providers: [locale_service_1.LocaleService, localization_service_1.LocalizationService, localization_pipe_1.LocalizationPipe], - pipes: [localization_pipe_1.LocalizationPipe] // Add in each component to invoke the transform method. - }), - router_1.RouteConfig([ - new router_1.AsyncRoute({ path: '/', loader: function () { return Promise.resolve(home_component_1.HomeComponent); }, name: 'Home', useAsDefault: true }), - new router_1.AsyncRoute({ path: '/i18n', loader: function () { return Promise.resolve(i18n_component_1.I18nComponent); }, name: 'I18n' }) - ]), - __metadata('design:paramtypes', [locale_service_1.LocaleService, localization_service_1.LocalizationService, router_1.Location]) - ], AppComponent); - return AppComponent; - }()); - exports_1("AppComponent", AppComponent); - } - } -}); diff --git a/app/app.component.ts b/app/app.component.ts deleted file mode 100644 index 760f7367..00000000 --- a/app/app.component.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {Component} from 'angular2/core'; -import {NgClass} from 'angular2/common'; -import {RouteConfig, AsyncRoute, Location, ROUTER_DIRECTIVES} from 'angular2/router'; -// Services. -import {LocaleService} from './services/locale.service'; // LocaleService class. -import {LocalizationService} from './services/localization.service'; // LocalizationService class. -// Pipes. -import {LocalizationPipe} from './pipes/localization.pipe'; // LocalizationPipe class. -// Components. -import {HomeComponent} from './home.component'; -import {I18nComponent} from './i18n.component'; - -@Component({ - selector: 'app-component', - directives: [ROUTER_DIRECTIVES, NgClass], - templateUrl: './app/app.component.html', // A component cannot have both pipes and @View set at the same time. - providers: [LocaleService, LocalizationService, LocalizationPipe], // Localization providers: inherited by all descendants. - pipes: [LocalizationPipe] // Add in each component to invoke the transform method. -}) - -@RouteConfig([ - new AsyncRoute({ path: '/', loader: () => Promise.resolve(HomeComponent), name: 'Home', useAsDefault: true }), - new AsyncRoute({ path: '/i18n', loader: () => Promise.resolve(I18nComponent), name: 'I18n' }) -]) - -export class AppComponent { - - constructor(public locale: LocaleService, public localization: LocalizationService, public location: Location) { - - // Initializes the LocaleService & LocalizationService: asynchronous loading. - this.locale.addLanguage('en'); // Required: adds a new language. - this.locale.addLanguage('it'); - - this.locale.definePreferredLanguage('en', 30); // Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie. - - this.localization.translationProvider('./resources/locale-'); // Required: initializes the translation provider with the given path prefix. - - } - - // Gets the current language. - get currentLanguage(): string { - - return this.locale.getCurrentLanguage(); - - } - - // Sets a new language. - selectLanguage(language) { - - this.locale.setCurrentLanguage(language); - - } - -} diff --git a/app/home.component.js b/app/home.component.js deleted file mode 100644 index 74184e63..00000000 --- a/app/home.component.js +++ /dev/null @@ -1,39 +0,0 @@ -System.register(['angular2/core', './pipes/localization.pipe'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1, localization_pipe_1; - var HomeComponent; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }, - function (localization_pipe_1_1) { - localization_pipe_1 = localization_pipe_1_1; - }], - execute: function() { - HomeComponent = (function () { - function HomeComponent() { - } - HomeComponent = __decorate([ - core_1.Component({ - template: "\n \n\n
\n\n
\n\n
\n\n
\n\n

{{ 'DUMMY_TEXT' | translate }}

\n \n\n
\n\n
\n\n
\n\n
\n ", - pipes: [localization_pipe_1.LocalizationPipe] - }), - __metadata('design:paramtypes', []) - ], HomeComponent); - return HomeComponent; - }()); - exports_1("HomeComponent", HomeComponent); - } - } -}); diff --git a/app/home.component.ts b/app/home.component.ts deleted file mode 100644 index 1ed9d572..00000000 --- a/app/home.component.ts +++ /dev/null @@ -1,35 +0,0 @@ -import {Component} from 'angular2/core'; -// Pipes. -import {LocalizationPipe} from './pipes/localization.pipe'; - -@Component({ - template: ` - - -
- -
- -
- -
- -

{{ 'DUMMY_TEXT' | translate }}

- - -
- -
- -
- -
- `, - pipes: [LocalizationPipe] -}) - -export class HomeComponent { - - constructor() { } - -} diff --git a/app/i18n.component.html b/app/i18n.component.html deleted file mode 100644 index 44d1ddcf..00000000 --- a/app/i18n.component.html +++ /dev/null @@ -1,39 +0,0 @@ - - -
- -
- -
- -

i18n

- -
- - - -
-
-

{{ gender | i18nSelect: inviteMapping | translate }}.

- -
- -
-
- -
- -
-
-

{{ messages.length | i18nPlural: messageMapping | translate}}.

-
- -
- -
- -
\ No newline at end of file diff --git a/app/i18n.component.js b/app/i18n.component.js deleted file mode 100644 index e7f961ba..00000000 --- a/app/i18n.component.js +++ /dev/null @@ -1,62 +0,0 @@ -System.register(['angular2/core', './services/localization.service', './pipes/localization.pipe'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1, localization_service_1, localization_pipe_1; - var I18nComponent; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }, - function (localization_service_1_1) { - localization_service_1 = localization_service_1_1; - }, - function (localization_pipe_1_1) { - localization_pipe_1 = localization_pipe_1_1; - }], - execute: function() { - I18nComponent = (function () { - // Instantiates a new LocalizationService for this component and for its descendants. - function I18nComponent(localizationI18n) { - this.localizationI18n = localizationI18n; - this.message = ""; - this.gender = "female"; - this.inviteMapping = { - 'male': 'INVITE_HIM', - 'female': 'INVITE_HER' - }; - this.messages = []; - this.messageMapping = { - '=0': 'NO_MESSAGES', - '=1': 'ONE_MESSAGE', - 'other': '# MESSAGES' - }; - this.localizationI18n.translationProvider('./resources/locale-i18n-'); // Required: initializes the translation provider with the given path prefix. - } - I18nComponent.prototype.addMessage = function (message) { - this.messages.push(message); - this.message = ""; - }; - I18nComponent = __decorate([ - core_1.Component({ - templateUrl: './app/i18n.component.html', - providers: [localization_service_1.LocalizationService, localization_pipe_1.LocalizationPipe], - pipes: [localization_pipe_1.LocalizationPipe] - }), - __metadata('design:paramtypes', [localization_service_1.LocalizationService]) - ], I18nComponent); - return I18nComponent; - }()); - exports_1("I18nComponent", I18nComponent); - } - } -}); diff --git a/app/i18n.component.ts b/app/i18n.component.ts deleted file mode 100644 index ba0f6750..00000000 --- a/app/i18n.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {Component} from 'angular2/core'; -// Services. -import {LocalizationService} from './services/localization.service'; -// Pipes. -import {LocalizationPipe} from './pipes/localization.pipe'; - -@Component({ - templateUrl: './app/i18n.component.html', - providers: [LocalizationService, LocalizationPipe], - pipes: [LocalizationPipe] -}) - -export class I18nComponent { - - message: string = ""; - - gender: string = "female"; - inviteMapping: any = { - 'male': 'INVITE_HIM', - 'female': 'INVITE_HER' - } - - messages: any = []; - messageMapping: any = { - '=0': 'NO_MESSAGES', - '=1': 'ONE_MESSAGE', - 'other': '# MESSAGES' - } - - // Instantiates a new LocalizationService for this component and for its descendants. - constructor(public localizationI18n: LocalizationService) { - - this.localizationI18n.translationProvider('./resources/locale-i18n-'); // Required: initializes the translation provider with the given path prefix. - - } - - addMessage(message: string) { - - this.messages.push(message); - this.message = ""; - - } - -} \ No newline at end of file diff --git a/app/main.js b/app/main.js deleted file mode 100644 index d779786c..00000000 --- a/app/main.js +++ /dev/null @@ -1,24 +0,0 @@ -/// -System.register(['angular2/platform/browser', 'angular2/http', 'angular2/router', './app.component'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var browser_1, http_1, router_1, app_component_1; - return { - setters:[ - function (browser_1_1) { - browser_1 = browser_1_1; - }, - function (http_1_1) { - http_1 = http_1_1; - }, - function (router_1_1) { - router_1 = router_1_1; - }, - function (app_component_1_1) { - app_component_1 = app_component_1_1; - }], - execute: function() { - browser_1.bootstrap(app_component_1.AppComponent, [router_1.ROUTER_PROVIDERS, http_1.HTTP_PROVIDERS]); - } - } -}); diff --git a/app/main.ts b/app/main.ts deleted file mode 100644 index 3c9776f9..00000000 --- a/app/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -/// - -import {bootstrap} from 'angular2/platform/browser' -import {HTTP_PROVIDERS} from 'angular2/http'; // Http module. -import {ROUTER_PROVIDERS} from 'angular2/router'; // Router module. -import {AppComponent} from './app.component' - -bootstrap(AppComponent, [ROUTER_PROVIDERS, HTTP_PROVIDERS]); \ No newline at end of file diff --git a/app/pipes/localization.pipe.js b/app/pipes/localization.pipe.js deleted file mode 100644 index 16c53ebf..00000000 --- a/app/pipes/localization.pipe.js +++ /dev/null @@ -1,101 +0,0 @@ -/** - * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license - * https://github.com/robisim74/angular2localization - */ -System.register(['angular2/core', '../services/locale.service', '../services/localization.service'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1, core_2, locale_service_1, localization_service_1; - var LocalizationPipe; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - core_2 = core_1_1; - }, - function (locale_service_1_1) { - locale_service_1 = locale_service_1_1; - }, - function (localization_service_1_1) { - localization_service_1 = localization_service_1_1; - }], - execute: function() { - /** - * Translate pipe function. - */ - LocalizationPipe = (function () { - function LocalizationPipe(locale, localization) { - this.locale = locale; - this.localization = localization; - } - /** - * Translate pipe transform method. - * - * @params key The key to be translated - * @return The value of the translation - */ - LocalizationPipe.prototype.transform = function (key) { - var _this = this; - // When the language changes, updates the language code and loads the translations data for the asynchronous loading. - if (this.locale.getCurrentLanguage() != "" && this.locale.getCurrentLanguage() != this.localization.languageCode) { - this.localization.updateTranslation(); - } - // Checks the service state. - if (this.localization.isReady) { - // Updates the key & the value of the translation for the key if: - // - the key is changed (i18n); - // - the value is empty; - // - the language is changed. - if (this.key != key || this.value == "" || this.languageCode != this.localization.languageCode) { - // i18n: remove the value of template locale variable. - var formatKey = key.replace(/^\d+\b/, ''); - formatKey = formatKey.trim(); - // Gets the value of the translation. - this.localization.translate(formatKey).forEach( - // Next. - function (value) { - _this.value = key.replace(formatKey, value); - }, null).then(function () { - // Updates the language code for the translate pipe. - _this.languageCode = _this.localization.languageCode; - // Updates the key of the translate pipe. - _this.key = key; - return _this.value; - }); - } - else { - // The value of the translation isn't changed. - return this.value; - } - } - else { - // The service isn't ready. - return this.value; - } - }; - LocalizationPipe = __decorate([ - core_2.Pipe({ - name: 'translate', - pure: false // Required to update the value. - }), - core_1.Injectable(), - __metadata('design:paramtypes', [locale_service_1.LocaleService, localization_service_1.LocalizationService]) - ], LocalizationPipe); - return LocalizationPipe; - }()); - exports_1("LocalizationPipe", LocalizationPipe); - } - } -}); diff --git a/app/services/locale.service.js b/app/services/locale.service.js deleted file mode 100644 index 6d854be3..00000000 --- a/app/services/locale.service.js +++ /dev/null @@ -1,153 +0,0 @@ -/** - * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license - * https://github.com/robisim74/angular2localization - */ -System.register(['angular2/core'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1; - var LocaleService; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }], - execute: function() { - /** - * LocaleService class. - * - * Instantiate this class only once in the route component in order to access the data of location from anywhere in the application. - * - * @author Roberto Simonetti - */ - LocaleService = (function () { - function LocaleService() { - /** - * The available languages codes. - */ - this.languageCodes = []; - this.languageCode = ""; - } - /** - * Asynchronous loading: adds a new language. - * - * @params language The two-letter code of the new language - */ - LocaleService.prototype.addLanguage = function (language) { - this.languageCodes.push(language); - }; - /** - * Direct & asynchronous loading: defines the preferred language. - * Selects the current language of the browser if it has been added, else the default language. - * - * @params defaultLanguage The two-letter code of the default language - * @params expiry Number of days on the expiry. If omitted, the cookie becomes a session cookie - */ - LocaleService.prototype.definePreferredLanguage = function (defaultLanguage, expiry) { - this.expiry = expiry; - // Tries to get the cookie "locale". - this.languageCode = this.getCookie("locale"); - if (this.languageCode == "") { - // Gets the current language of the browser or the default language. - var browserLanguage = navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage; - browserLanguage = browserLanguage.substring(0, 2); // Gets the two-letter code. - if (this.languageCodes.indexOf(browserLanguage) != -1) { - this.languageCode = browserLanguage; - } - else { - this.languageCode = defaultLanguage; - } - // Sets the cookie "locale". - this.setCookie("locale", this.languageCode, this.expiry); - } - }; - /** - * Gets the current language. - * - * @return The two-letter code of the current language - */ - LocaleService.prototype.getCurrentLanguage = function () { - return this.languageCode; - }; - /** - * Sets the current language. - * - * @params language The two-letter code of the new language - */ - LocaleService.prototype.setCurrentLanguage = function (language) { - // Checks if the language is changed. - if (this.languageCode != language) { - // Sets the current language code. - this.languageCode = language; - // Sets the cookie "locale". - this.setCookie("locale", language, this.expiry); - } - }; - /** - * Sets the cookie. - * - * @params name The name of the cookie - * @params value The language code - * @params days Number of days on the expiry - */ - LocaleService.prototype.setCookie = function (name, value, days) { - if (days != null) { - // Adds the expiry date (in UTC time). - var expirationDate = new Date(); - expirationDate.setTime(expirationDate.getTime() + (days * 24 * 60 * 60 * 1000)); - var expires = "; expires=" + expirationDate.toUTCString(); - } - else { - // By default, the cookie is deleted when the browser is closed. - var expires = ""; - } - // Creates the cookie. - document.cookie = name + "=" + value + expires + "; path=/"; - }; - /** - * Gets the cookie. - * - * @params name The name of the cookie - * @return The language code - */ - LocaleService.prototype.getCookie = function (name) { - // The text to search for. - name += "="; - // Splits document.cookie on semicolons into an array. - var ca = document.cookie.split(';'); - // Loops through the ca array, and reads out each value. - for (var i = 0; i < ca.length; i++) { - var c = ca[i]; - while (c.charAt(0) == ' ') { - c = c.substring(1); - } - // If the cookie is found, returns the value of the cookie. - if (c.indexOf(name) == 0) { - return c.substring(name.length, c.length); - } - } - // If the cookie is not found, returns an empty string. - return ""; - }; - LocaleService = __decorate([ - core_1.Injectable(), - __metadata('design:paramtypes', []) - ], LocaleService); - return LocaleService; - }()); - exports_1("LocaleService", LocaleService); - } - } -}); diff --git a/app/services/locale.service.ts b/app/services/locale.service.ts deleted file mode 100644 index 198f7b7f..00000000 --- a/app/services/locale.service.ts +++ /dev/null @@ -1,188 +0,0 @@ -/** - * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license - * https://github.com/robisim74/angular2localization - */ - -import {Injectable} from 'angular2/core'; - -/** - * LocaleService class. - * - * Instantiate this class only once in the route component in order to access the data of location from anywhere in the application. - * - * @author Roberto Simonetti - */ -@Injectable() export class LocaleService { - - /** - * Current language code. - */ - private languageCode: string; - - /** - * The available languages codes. - */ - private languageCodes: Array = []; - - /** - * Defines when the cookie will be removed. - */ - private expiry: number; - - constructor() { - - this.languageCode = ""; - - } - - /** - * Asynchronous loading: adds a new language. - * - * @params language The two-letter code of the new language - */ - addLanguage(language: string) { - - this.languageCodes.push(language); - - } - - /** - * Direct & asynchronous loading: defines the preferred language. - * Selects the current language of the browser if it has been added, else the default language. - * - * @params defaultLanguage The two-letter code of the default language - * @params expiry Number of days on the expiry. If omitted, the cookie becomes a session cookie - */ - definePreferredLanguage(defaultLanguage: string, expiry?: number) { - - this.expiry = expiry; - - // Tries to get the cookie "locale". - this.languageCode = this.getCookie("locale"); - - if (this.languageCode == "") { - - // Gets the current language of the browser or the default language. - var browserLanguage: string = navigator.language || navigator.userLanguage || navigator.browserLanguage || navigator.systemLanguage; - - browserLanguage = browserLanguage.substring(0, 2); // Gets the two-letter code. - - if (this.languageCodes.indexOf(browserLanguage) != -1) { - - this.languageCode = browserLanguage; - - } else { - - this.languageCode = defaultLanguage; - - } - - // Sets the cookie "locale". - this.setCookie("locale", this.languageCode, this.expiry); - - } - - } - - /** - * Gets the current language. - * - * @return The two-letter code of the current language - */ - getCurrentLanguage(): string { - - return this.languageCode; - - } - - /** - * Sets the current language. - * - * @params language The two-letter code of the new language - */ - setCurrentLanguage(language: string) { - - // Checks if the language is changed. - if (this.languageCode != language) { - - // Sets the current language code. - this.languageCode = language; - - // Sets the cookie "locale". - this.setCookie("locale", language, this.expiry); - - } - - } - - /** - * Sets the cookie. - * - * @params name The name of the cookie - * @params value The language code - * @params days Number of days on the expiry - */ - private setCookie(name: string, value: string, days?: number) { - - if (days != null) { - - // Adds the expiry date (in UTC time). - var expirationDate: Date = new Date(); - - expirationDate.setTime(expirationDate.getTime() + (days * 24 * 60 * 60 * 1000)); - - var expires: string = "; expires=" + expirationDate.toUTCString(); - - } else { - - // By default, the cookie is deleted when the browser is closed. - var expires: string = ""; - - } - - // Creates the cookie. - document.cookie = name + "=" + value + expires + "; path=/"; - - } - - /** - * Gets the cookie. - * - * @params name The name of the cookie - * @return The language code - */ - private getCookie(name: string): string { - - // The text to search for. - name += "="; - - // Splits document.cookie on semicolons into an array. - var ca: string[] = document.cookie.split(';'); - - // Loops through the ca array, and reads out each value. - for (var i = 0; i < ca.length; i++) { - - var c: string = ca[i]; - - while (c.charAt(0) == ' ') { - - c = c.substring(1); - - } - // If the cookie is found, returns the value of the cookie. - if (c.indexOf(name) == 0) { - - return c.substring(name.length, c.length); - - } - } - - // If the cookie is not found, returns an empty string. - return ""; - - } - -} \ No newline at end of file diff --git a/app/services/localization.service.js b/app/services/localization.service.js deleted file mode 100644 index a2a29231..00000000 --- a/app/services/localization.service.js +++ /dev/null @@ -1,247 +0,0 @@ -/** - * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license - * https://github.com/robisim74/angular2localization - */ -System.register(['angular2/core', 'angular2/http', 'rxjs/Observable', 'rxjs/add/operator/map', './locale.service'], function(exports_1, context_1) { - "use strict"; - var __moduleName = context_1 && context_1.id; - var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - }; - var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); - }; - var core_1, http_1, Observable_1, locale_service_1; - var LocalizationService; - return { - setters:[ - function (core_1_1) { - core_1 = core_1_1; - }, - function (http_1_1) { - http_1 = http_1_1; - }, - function (Observable_1_1) { - Observable_1 = Observable_1_1; - }, - function (_1) {}, - function (locale_service_1_1) { - locale_service_1 = locale_service_1_1; - }], - execute: function() { - /** - * LocalizationService class. - * - * How to use the translation service. - * - * // Services. - * import {LocaleService} from './services/locale.service'; // LocaleService class. - * import {LocalizationService} from './services/localization.service'; // LocalizationService class. - * // Pipes. - * import {LocalizationPipe} from './pipes/localization.pipe'; // LocalizationPipe class. - * - * @Component({ - * selector: 'app-component', - * ... - * providers: [LocaleService, LocalizationService, LocalizationPipe], // Localization providers: inherited by all descendants. - * pipes: [LocalizationPipe] // Add in each component to invoke the transform method. - * }) - * - * export class AppComponent { - * - * constructor(public locale: LocaleService, public localization: LocalizationService) { - * - * // Initializes the LocaleService. - * this.locale.addLanguage('en'); // Required: adds a new language. - * this.locale.addLanguage('it'); - * ... - * this.locale.definePreferredLanguage('en', 30); // Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie. - * - * } - * - * } - * - * Also add in the main: - * - * bootstrap(AppComponent, [HTTP_PROVIDERS]); - * - * Direct loading. - * - * To initialize the LocalizationService for the direct loading, add the following code in the body of the constructor of the route component: - * - * var translationEN = { - * TITLE: 'ANGULAR 2 LOCALIZATION', - * CHANGE_LANGUAGE: 'change language', - * ... - * } - * // Add a new translation here. - * - * this.localization.addTranslation('en', translationEN); // Required: adds a new translation with the given language code. - * this.localization.addTranslation('it', translationIT); - * ... - * - * Asynchronous loading. - * - * To initialize the LocalizationService for the asynchronous loading add the following code in the body of the constructor of the route component: - * - * this.localization.translationProvider('./resources/locale-'); // Required: Initializes the translation provider with the given path prefix. - * - * and create the json files of the translations such as "locale-en.json": - * - * { - * "TITLE": "angular 2 localization", - * "CHANGE_LANGUAGE": "change language", - * ... - * } - * - * Special characters. - * - * Use the escape character \ to insert special characters into the values of the translations: - * - * \' single quote - * \" double quote - * - * Getting the translation. - * - * To get the translation, add in the template: - * - * {{ 'EXAMPLE' | translate }} - * - * and in each component: - * - * @Component({ - * ... - * pipes: [LocalizationPipe] - * }) - * - * Changing language. - * - * To change language at runtime, add in the component: - * - * selectLanguage(language) { - * - * this.locale.setCurrentLanguage(language); - * - * } - * - * where "language" is the two-letter code of the language; then add in the view: - * - * English - * ... - * - * @author Roberto Simonetti - */ - LocalizationService = (function () { - function LocalizationService(http, locale) { - this.http = http; - this.locale = locale; - /** - * The translations data: {locale: {key: value}}. - */ - this.translationsData = {}; - this.prefix = ""; - this.languageCode = ""; - // Initializes the service state. - this.isReady = false; - } - /** - * Direct loading: adds new translation data. - * - * @params language The two-letter code of the language for the translation data - * @params translation The new translation data - */ - LocalizationService.prototype.addTranslation = function (language, translation) { - // Adds the new translation data. - this.translationsData[language] = translation; - // Updates the service state. - this.isReady = true; - }; - /** - * Asinchronous loading: defines the translation provider. - * - * @params prefix The path prefix of the json files - */ - LocalizationService.prototype.translationProvider = function (prefix) { - this.prefix = prefix; - }; - /** - * Gets the json data. - */ - LocalizationService.prototype.getTranslation = function () { - var _this = this; - // Initializes the translations data & the service state. - this.translationsData = {}; - this.isReady = false; - var url = this.prefix + this.languageCode + '.json'; - // Angular 2 Http module. - this.http.get(url) - .map(function (res) { return res.json(); }) - .subscribe( - // Observer or next. - function (res) { - // Assigns the observer to the traslations data. - _this.translationsData[_this.languageCode] = res; - }, - // Error. - function (error) { - console.error("Localization service:", error); - }, - // Complete. - function () { - // Updates the service state. - _this.isReady = true; - console.log("Localization service:", "Http get method completed."); - }); - }; - /** - * Translate a key. - * - * @params key The key to be translated - * @return An observable of the value of the translation - */ - LocalizationService.prototype.translate = function (key) { - var _this = this; - return new Observable_1.Observable(function (observer) { - var value; - if (_this.translationsData[_this.languageCode] != null) { - // Gets the translation by language code. - var translation = _this.translationsData[_this.languageCode]; - // Gets the value of the translation by key. - value = translation[key]; - } - // If the value of the translation is not present, the same key is returned (see issue #1). - if (value == null || value == "") { - value = key; - } - observer.next(value); - observer.complete(); - }); - }; - /** - * When the language changes, updates the language code and loads the translations data for the asynchronous loading. - */ - LocalizationService.prototype.updateTranslation = function () { - // Updates the language code for the service. - this.languageCode = this.locale.getCurrentLanguage(); - // Asynchronous loading. - if (this.prefix != "") { - // Updates the translations data. - this.getTranslation(); - } - }; - LocalizationService = __decorate([ - core_1.Injectable(), - __metadata('design:paramtypes', [http_1.Http, locale_service_1.LocaleService]) - ], LocalizationService); - return LocalizationService; - }()); - exports_1("LocalizationService", LocalizationService); - } - } -}); diff --git a/app/services/localization.service.ts b/app/services/localization.service.ts deleted file mode 100644 index db8b7f09..00000000 --- a/app/services/localization.service.ts +++ /dev/null @@ -1,275 +0,0 @@ -/** - * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license - * https://github.com/robisim74/angular2localization - */ - -import {Injectable} from 'angular2/core'; -import {Http, Response} from 'angular2/http'; -import {Observer} from 'rxjs/Observer'; -import {Observable} from 'rxjs/Observable'; -import 'rxjs/add/operator/map'; - -import {LocaleService} from './locale.service'; - -/** - * LocalizationService class. - * - * How to use the translation service. - * - * // Services. - * import {LocaleService} from './services/locale.service'; // LocaleService class. - * import {LocalizationService} from './services/localization.service'; // LocalizationService class. - * // Pipes. - * import {LocalizationPipe} from './pipes/localization.pipe'; // LocalizationPipe class. - * - * @Component({ - * selector: 'app-component', - * ... - * providers: [LocaleService, LocalizationService, LocalizationPipe], // Localization providers: inherited by all descendants. - * pipes: [LocalizationPipe] // Add in each component to invoke the transform method. - * }) - * - * export class AppComponent { - * - * constructor(public locale: LocaleService, public localization: LocalizationService) { - * - * // Initializes the LocaleService. - * this.locale.addLanguage('en'); // Required: adds a new language. - * this.locale.addLanguage('it'); - * ... - * this.locale.definePreferredLanguage('en', 30); // Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie. - * - * } - * - * } - * - * Also add in the main: - * - * bootstrap(AppComponent, [HTTP_PROVIDERS]); - * - * Direct loading. - * - * To initialize the LocalizationService for the direct loading, add the following code in the body of the constructor of the route component: - * - * var translationEN = { - * TITLE: 'ANGULAR 2 LOCALIZATION', - * CHANGE_LANGUAGE: 'change language', - * ... - * } - * // Add a new translation here. - * - * this.localization.addTranslation('en', translationEN); // Required: adds a new translation with the given language code. - * this.localization.addTranslation('it', translationIT); - * ... - * - * Asynchronous loading. - * - * To initialize the LocalizationService for the asynchronous loading add the following code in the body of the constructor of the route component: - * - * this.localization.translationProvider('./resources/locale-'); // Required: Initializes the translation provider with the given path prefix. - * - * and create the json files of the translations such as "locale-en.json": - * - * { - * "TITLE": "angular 2 localization", - * "CHANGE_LANGUAGE": "change language", - * ... - * } - * - * Special characters. - * - * Use the escape character \ to insert special characters into the values of the translations: - * - * \' single quote - * \" double quote - * - * Getting the translation. - * - * To get the translation, add in the template: - * - * {{ 'EXAMPLE' | translate }} - * - * and in each component: - * - * @Component({ - * ... - * pipes: [LocalizationPipe] - * }) - * - * Changing language. - * - * To change language at runtime, add in the component: - * - * selectLanguage(language) { - * - * this.locale.setCurrentLanguage(language); - * - * } - * - * where "language" is the two-letter code of the language; then add in the view: - * - * English - * ... - * - * @author Roberto Simonetti - */ -@Injectable() export class LocalizationService { - - /** - * The path prefix for the asynchronous loading. - */ - private prefix: string; - - /** - * The translations data: {locale: {key: value}}. - */ - private translationsData: any = {}; - - /** - * The language code for the service. - */ - public languageCode: string; - - /** - * The service state. - */ - public isReady; - - constructor(public http: Http, public locale: LocaleService) { - - this.prefix = ""; - - this.languageCode = ""; - - // Initializes the service state. - this.isReady = false; - - } - - /** - * Direct loading: adds new translation data. - * - * @params language The two-letter code of the language for the translation data - * @params translation The new translation data - */ - addTranslation(language: string, translation: any) { - - // Adds the new translation data. - this.translationsData[language] = translation; - - // Updates the service state. - this.isReady = true; - - } - - /** - * Asinchronous loading: defines the translation provider. - * - * @params prefix The path prefix of the json files - */ - translationProvider(prefix: string) { - - this.prefix = prefix; - - } - - /** - * Gets the json data. - */ - private getTranslation() { - - // Initializes the translations data & the service state. - this.translationsData = {}; - this.isReady = false; - - var url: string = this.prefix + this.languageCode + '.json'; - - // Angular 2 Http module. - this.http.get(url) - .map((res: Response) => res.json()) - .subscribe( - - // Observer or next. - (res: any) => { - - // Assigns the observer to the traslations data. - this.translationsData[this.languageCode] = res; - - }, - - // Error. - (error: any) => { - - console.error("Localization service:", error); - - }, - - // Complete. - () => { - - // Updates the service state. - this.isReady = true; - - console.log("Localization service:", "Http get method completed."); - - }); - - } - - /** - * Translate a key. - * - * @params key The key to be translated - * @return An observable of the value of the translation - */ - translate(key: string): Observable { - - return new Observable((observer: Observer) => { - - var value: string; - - if (this.translationsData[this.languageCode] != null) { - - // Gets the translation by language code. - var translation: any = this.translationsData[this.languageCode]; - // Gets the value of the translation by key. - value = translation[key]; - - } - - // If the value of the translation is not present, the same key is returned (see issue #1). - if (value == null || value == "") { - - value = key; - - } - - observer.next(value); - observer.complete(); - - }); - - } - - /** - * When the language changes, updates the language code and loads the translations data for the asynchronous loading. - */ - updateTranslation() { - - // Updates the language code for the service. - this.languageCode = this.locale.getCurrentLanguage(); - - // Asynchronous loading. - if (this.prefix != "") { - - // Updates the translations data. - this.getTranslation(); - - } - - } - -} \ No newline at end of file diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index a3a79998..00000000 Binary files a/favicon.ico and /dev/null differ diff --git a/gulpfile.js b/gulpfile.js index cbb94f9f..b3df29b8 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,25 +1,49 @@ // Plug-ins. -const gulp = require('gulp'); -const del = require('del'); +var gulp = require('gulp'), + del = require('del'); + +// Script paths. +var path = require("path"), + dest = 'bundles'; + +// SystemJS Build Tool. +var Builder = require('systemjs-builder'); + +var builder = new Builder(); + +var config = { + baseURL: path.baseURL, + defaultJSExtensions: true, + map: { + 'angular2': 'node_modules/angular2', + 'rxjs': 'node_modules/rxjs' + }, + paths: { + 'angular2localization/*': '*.js', + }, + meta: { + 'node_modules/angular2/*': { build: false }, + 'node_modules/rxjs/*': { build: false } + } +}; + +builder.config(config); + +// Clean task: cleans the contents of the bundles directory. +gulp.task('clean', function() { + + return del(dest); -// Cleans the contents of the distribution directory. -gulp.task('clean', function () { - return del('dist/**/*'); }); -// Copies dependencies. -gulp.task('copy:libs', ['clean'], function () { - return gulp.src([ - 'node_modules/es6-shim/es6-shim.min.js', - 'node_modules/systemjs/dist/system-polyfills.js', - 'node_modules/angular2/bundles/angular2-polyfills.js', - 'node_modules/systemjs/dist/system.src.js', - 'node_modules/rxjs/bundles/Rx.js', - 'node_modules/angular2/bundles/angular2.dev.js', - 'node_modules/angular2/bundles/http.dev.js', - 'node_modules/angular2/bundles/router.dev.js' - ]) - .pipe(gulp.dest('dist/lib')) +// Bundles task: creates bundles files. +gulp.task('bundles', ['clean'], function() { + + // Creates js file. + builder.bundle('angular2localization/angular2localization', dest + '/angular2localization.js', { minify: false, sourceMaps: false }); + // Creates minified js file. + builder.bundle('angular2localization/angular2localization', dest + '/angular2localization.min.js', { minify: true, sourceMaps: false }); + }); -gulp.task('default', ['copy:libs']); \ No newline at end of file +gulp.task('default', ['bundles']); \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index 391d43be..00000000 --- a/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - - - - - - Angular 2 Localization - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/package.json b/package.json index 68fe600b..ff480044 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,10 @@ { "name": "angular2localization", - "version": "1.0.0", - "description": "A translation service for the new Angular 2 applications using TypeScript", + "version": "0.4.0", + "description": "An Angular 2 library for i18n and l10n that implements a translation service - using TypeScript and SystemJS", "main": "", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], + "scripts": {}, + "keywords": ["angular2", "typescript", "SystemJS", "internationalization", "i18n", "localization", "l10n", "translation"], "author": "Roberto Simonetti", "license": "MIT", "repository": { @@ -17,17 +15,19 @@ "url": "https://github.com/robisim74/angular2localization/issues" }, "homepage": "https://github.com/robisim74/angular2localization", + "typings": "./angular2localization.d.ts", "dependencies": { - "angular2": "2.0.0-beta.10", + "angular2": "2.0.0-beta.13", "systemjs": "0.19.24", - "es6-promise": "^3.1.2", "es6-shim": "^0.35.0", - "reflect-metadata": "0.1.3", + "reflect-metadata": "0.1.2", "rxjs": "5.0.0-beta.2", - "zone.js": "^0.6.4" + "zone.js": "0.6.6" }, "devDependencies": { + "typescript": "^1.8.9", "gulp": "^3.9.1", - "del": "^2.2.0" + "del": "^2.2.0", + "systemjs-builder": "^0.15.13" } } \ No newline at end of file diff --git a/resources/locale-en.json b/resources/locale-en.json deleted file mode 100644 index 6958feed..00000000 --- a/resources/locale-en.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "TITLE": "angular 2 localization", - "I18N": "i18n", - "CHANGE_LANGUAGE": "change language", - "DUMMY_TEXT": "One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready to slide off any moment. His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked. \"What's happened to me?\" he thought. It wasn't a dream.", - "AUTHOR": "Kafka", - "SOURCE_TITLE": "The Metamorphosis" -} \ No newline at end of file diff --git a/resources/locale-i18n-en.json b/resources/locale-i18n-en.json deleted file mode 100644 index 9100f1fd..00000000 --- a/resources/locale-i18n-en.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "FEMALE": "female", - "MALE": "male", - "INVITE_HER": "Invite her", - "INVITE_HIM": "Invite him", - "ADD_MESSAGE": "add new message", - "ADD": "add", - "NO_MESSAGES": "No messages", - "ONE_MESSAGE": "One message", - "MESSAGES": "messages" -} \ No newline at end of file diff --git a/resources/locale-i18n-it.json b/resources/locale-i18n-it.json deleted file mode 100644 index 4b8e1394..00000000 --- a/resources/locale-i18n-it.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "FEMALE": "femmina", - "MALE": "maschio", - "INVITE_HER": "Invitala", - "INVITE_HIM": "Invitalo", - "ADD_MESSAGE": "aggiungi un nuovo messaggio", - "ADD": "aggiungi", - "NO_MESSAGES": "Nessun messaggio", - "ONE_MESSAGE": "Un messaggio", - "MESSAGES": "messaggi" -} \ No newline at end of file diff --git a/resources/locale-it.json b/resources/locale-it.json deleted file mode 100644 index f02ed9c8..00000000 --- a/resources/locale-it.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "TITLE": "angular 2 localization", - "I18N": "i18n", - "CHANGE_LANGUAGE": "cambia lingua", - "DUMMY_TEXT": "Gregorio Samsa, svegliandosi una mattina da sogni agitati, si trovò trasformato, nel suo letto, in un enorme insetto immondo. Riposava sulla schiena, dura come una corazza, e sollevando un poco il capo vedeva il suo ventre arcuato, bruno e diviso in tanti segmenti ricurvi, in cima a cui la coperta da letto, vicina a scivolar giù tutta, si manteneva a fatica. Le gambe, numerose e sottili da far pietà, rispetto alla sua corporatura normale, tremolavano senza tregua in un confuso luccichio dinanzi ai suoi occhi. Cosa m'è avvenuto? pensò. Non era un sogno.", - "AUTHOR": "Kafka", - "SOURCE_TITLE": "La metamorfosi" -} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 00000000..db57a4bb --- /dev/null +++ b/src/main.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/src/pipes/localization.pipe.ts b/src/pipes/localization.pipe.ts deleted file mode 100644 index 629360f6..00000000 --- a/src/pipes/localization.pipe.ts +++ /dev/null @@ -1,116 +0,0 @@ -/** - * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license - * https://github.com/robisim74/angular2localization - */ - -import {Injectable} from 'angular2/core'; -import {Pipe, PipeTransform} from 'angular2/core'; -// Services. -import {LocaleService} from '../services/locale.service'; -import {LocalizationService} from '../services/localization.service'; - -/** - * Translate pipe function. - */ -@Pipe({ - name: 'translate', - pure: false // Required to update the value. -}) - -/** - * LocalizationPipe class. - * - * An instance of this class is created for each translate pipe function. - * - * @author Roberto Simonetti - */ -@Injectable() export class LocalizationPipe implements PipeTransform { - - /** - * The language code for the translate pipe. - */ - private languageCode: string; - - /** - * The key of the translate pipe. - */ - private key: string; - - /** - * The value of the translation for the key. - */ - private value: string; - - constructor(public locale: LocaleService, public localization: LocalizationService) { } - - /** - * Translate pipe transform method. - * - * @params key The key to be translated - * @return The value of the translation - */ - transform(key: string): string { - - // When the language changes, updates the language code and loads the translations data for the asynchronous loading. - if (this.locale.getCurrentLanguage() != "" && this.locale.getCurrentLanguage() != this.localization.languageCode) { - - this.localization.updateTranslation(); - - } - - // Checks the service state. - if (this.localization.isReady) { - - // Updates the key & the value of the translation for the key if: - // - the key is changed (i18n); - // - the value is empty; - // - the language is changed. - if (this.key != key || this.value == "" || this.languageCode != this.localization.languageCode) { - - // i18n: remove the value of template locale variable. - var formatKey: string = key.replace(/^\d+\b/, ''); - formatKey = formatKey.trim(); - - // Gets the value of the translation. - this.localization.translate(formatKey).forEach( - - // Next. - (value: string) => { - - this.value = key.replace(formatKey, value); - - }, null - - ).then( - - () => { - - // Updates the language code for the translate pipe. - this.languageCode = this.localization.languageCode; - // Updates the key of the translate pipe. - this.key = key; - - return this.value; - - }); - - } else { - - // The value of the translation isn't changed. - return this.value; - - } - - } else { - - // The service isn't ready. - return this.value; - - } - - } - -} \ No newline at end of file diff --git a/app/pipes/localization.pipe.ts b/src/pipes/translate.pipe.ts similarity index 79% rename from app/pipes/localization.pipe.ts rename to src/pipes/translate.pipe.ts index 629360f6..653bd25e 100644 --- a/app/pipes/localization.pipe.ts +++ b/src/pipes/translate.pipe.ts @@ -1,8 +1,8 @@ /** * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license + * An Angular 2 library for i18n and l10n that implements a translation service - using TypeScript and SystemJS. + * Written by Roberto Simonetti. + * MIT license. * https://github.com/robisim74/angular2localization */ @@ -21,13 +21,33 @@ import {LocalizationService} from '../services/localization.service'; }) /** - * LocalizationPipe class. - * + * TranslatePipe class. * An instance of this class is created for each translate pipe function. * + * Getting the translation. + * + * To get the translation, add in the template: + * + * {{ 'TITLE' | translate }} + * + * and in each component: + * + * @Component({ + * ... + * pipes: [TranslatePipe] + * }) + * + * With 'I18n Select' that displays the string that matches the current value: + * + * {{ gender | i18nSelect: inviteMapping | translate }} + * + * With 'I18n Plural' that pluralizes the value properly: + * + * {{ messages.length | i18nPlural: messageMapping | translate }} + * * @author Roberto Simonetti */ -@Injectable() export class LocalizationPipe implements PipeTransform { +@Injectable() export class TranslatePipe implements PipeTransform { /** * The language code for the translate pipe. diff --git a/src/services/locale.service.ts b/src/services/locale.service.ts index 198f7b7f..ef97969e 100644 --- a/src/services/locale.service.ts +++ b/src/services/locale.service.ts @@ -1,8 +1,8 @@ /** * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license + * An Angular 2 library for i18n and l10n that implements a translation service - using TypeScript and SystemJS. + * Written by Roberto Simonetti. + * MIT license. * https://github.com/robisim74/angular2localization */ @@ -11,8 +11,54 @@ import {Injectable} from 'angular2/core'; /** * LocaleService class. * - * Instantiate this class only once in the route component in order to access the data of location from anywhere in the application. + * Instantiate this class only once in the route component in order to access the data of location from anywhere in the application: * + * // Services. + * import {LocaleService} from 'angular2localization/angular2localization'; // LocaleService class. + * import {LocalizationService} from 'angular2localization/angular2localization'; // LocalizationService class. + * // Pipes. + * import {TranslatePipe} from 'angular2localization/angular2localization'; // TranslatePipe class. + * + * @Component({ + * selector: 'app-component', + * ... + * providers: [LocaleService, LocalizationService, TranslatePipe], // Localization providers: inherited by all descendants. + * pipes: [TranslatePipe] // Add in each component to invoke the transform method. + * }) + * + * export class AppComponent { + * + * constructor(public locale: LocaleService, public localization: LocalizationService) { + * + * // Initializes the LocaleService. + * this.locale.addLanguage('en'); // Required: adds a new language. + * this.locale.addLanguage('it'); + * ... + * this.locale.definePreferredLanguage('en', 30); // Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie. + * + * } + * + * } + * + * Also add in the main: + * + * bootstrap(AppComponent, [HTTP_PROVIDERS]); + * + * Changing language. + * + * To change language at runtime, add in the component: + * + * selectLanguage(language: string) { + * + * this.locale.setCurrentLanguage(language); + * + * } + * + * where 'language' is the two-letter code of the language; then add in the view: + * + * English + * ... + * * @author Roberto Simonetti */ @Injectable() export class LocaleService { diff --git a/src/services/localization.service.ts b/src/services/localization.service.ts index db8b7f09..dd3fa422 100644 --- a/src/services/localization.service.ts +++ b/src/services/localization.service.ts @@ -1,8 +1,8 @@ /** * ANGULAR 2 LOCALIZATION - * A translation service for the new Angular 2 applications using TypeScript - * written by Roberto Simonetti - * MIT license + * An Angular 2 library for i18n and l10n that implements a translation service - using TypeScript and SystemJS. + * Written by Roberto Simonetti. + * MIT license. * https://github.com/robisim74/angular2localization */ @@ -17,45 +17,12 @@ import {LocaleService} from './locale.service'; /** * LocalizationService class. * - * How to use the translation service. - * - * // Services. - * import {LocaleService} from './services/locale.service'; // LocaleService class. - * import {LocalizationService} from './services/localization.service'; // LocalizationService class. - * // Pipes. - * import {LocalizationPipe} from './pipes/localization.pipe'; // LocalizationPipe class. - * - * @Component({ - * selector: 'app-component', - * ... - * providers: [LocaleService, LocalizationService, LocalizationPipe], // Localization providers: inherited by all descendants. - * pipes: [LocalizationPipe] // Add in each component to invoke the transform method. - * }) - * - * export class AppComponent { - * - * constructor(public locale: LocaleService, public localization: LocalizationService) { - * - * // Initializes the LocaleService. - * this.locale.addLanguage('en'); // Required: adds a new language. - * this.locale.addLanguage('it'); - * ... - * this.locale.definePreferredLanguage('en', 30); // Required: default language and expiry (No days). If the expiry is omitted, the cookie becomes a session cookie. - * - * } - * - * } - * - * Also add in the main: - * - * bootstrap(AppComponent, [HTTP_PROVIDERS]); - * * Direct loading. * * To initialize the LocalizationService for the direct loading, add the following code in the body of the constructor of the route component: * * var translationEN = { - * TITLE: 'ANGULAR 2 LOCALIZATION', + * TITLE: 'angular 2 localization', * CHANGE_LANGUAGE: 'change language', * ... * } @@ -71,7 +38,7 @@ import {LocaleService} from './locale.service'; * * this.localization.translationProvider('./resources/locale-'); // Required: Initializes the translation provider with the given path prefix. * - * and create the json files of the translations such as "locale-en.json": + * and create the json files of the translations such as 'locale-en.json': * * { * "TITLE": "angular 2 localization", @@ -81,38 +48,13 @@ import {LocaleService} from './locale.service'; * * Special characters. * - * Use the escape character \ to insert special characters into the values of the translations: - * - * \' single quote - * \" double quote - * - * Getting the translation. - * - * To get the translation, add in the template: - * - * {{ 'EXAMPLE' | translate }} - * - * and in each component: - * - * @Component({ - * ... - * pipes: [LocalizationPipe] - * }) - * - * Changing language. - * - * To change language at runtime, add in the component: - * - * selectLanguage(language) { - * - * this.locale.setCurrentLanguage(language); - * - * } - * - * where "language" is the two-letter code of the language; then add in the view: + * You can use quotes inside a string, as long as they don't match the quotes surrounding the string: + * + * "It wasn't a dream." + * + * Because strings must be written within quotes, use the '\' escape character to insert special characters into the values of the translations: * - * English - * ... + * "\"What's happened to me?\" he thought." * * @author Roberto Simonetti */ @@ -136,7 +78,7 @@ import {LocaleService} from './locale.service'; /** * The service state. */ - public isReady; + public isReady: boolean; constructor(public http: Http, public locale: LocaleService) { diff --git a/tsconfig.json b/tsconfig.json index fe1ae3ed..629c4a8e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,14 +3,14 @@ "target": "es5", "module": "system", "moduleResolution": "node", - "sourceMap": false, + "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, - "noImplicitAny": false + "noImplicitAny": true, + "declaration": true }, "exclude": [ - "node_modules", - "src" + "node_modules" ] } \ No newline at end of file