├── .gitignore
├── .travis.yml
├── bower.json
├── CONTRIBUTING.md
├── .jscs.json
├── karma.conf.js
├── karma.min.conf.js
├── LICENSE
├── package.json
├── Gruntfile.js
├── README.md
├── tmhDynamicLocale.min.js
├── tmhDynamicLocale.min.js.map
├── src
└── tmhDynamicLocale.js
└── test
└── tmhDynamicLocaleSpec.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | components
3 | .rcs
4 | *.swp
5 | .idea
6 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 0.10
4 |
5 | before_install:
6 | - npm install -g grunt-cli bower
7 |
8 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Lucas Galfaso",
3 | "name": "angular-dynamic-locale",
4 | "main": "src/tmhDynamicLocale.js",
5 | "description": "Angular Dynamic Locale",
6 | "version": "0.1.23",
7 | }
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | CONTRIBUTING
2 | ============
3 |
4 | * Open a [Pull Request (PR)](https://github.com/lgalfaso/angular-dynamic-locale/pull/new/master)
5 | * Make sure your PR is on a **new branch** you created off of the latest version of master
6 | * Do **not** open a PR from your master branch
7 | * Open a PR to start a discussion even if the code isn't finished (easier to collect feedback this way)
8 | * Make sure all previous tests pass and add new tests for added behaviors
9 |
--------------------------------------------------------------------------------
/.jscs.json:
--------------------------------------------------------------------------------
1 | {
2 | "disallowKeywords": ["with"],
3 | "disallowMixedSpacesAndTabs": true,
4 | "disallowMultipleLineStrings": true,
5 | "disallowNewlineBeforeBlockStatements": true,
6 | "disallowSpaceAfterObjectKeys": true,
7 | "disallowSpaceAfterPrefixUnaryOperators": ["!"],
8 | "disallowSpaceBeforeBinaryOperators": [","],
9 | "disallowSpacesInsideParentheses": true,
10 | "disallowTrailingComma": true,
11 | "disallowTrailingWhitespace": true,
12 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"],
13 | "validateParameterSeparator": ", "
14 | }
15 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 | config.set({
3 | autoWatch: false,
4 | singleRun: true,
5 | logLevel: config.LOG_INFO,
6 | logColors: true,
7 | browsers: ['Chrome'],
8 | files: [
9 | 'node_modules/angular/angular.js',
10 | 'node_modules/angular-cookies/angular-cookies.js',
11 | 'node_modules/angular-mocks/angular-mocks.js',
12 | {pattern: 'node_modules/angular-i18n/*.js', included: false, served: true},
13 | 'src/*.js',
14 | 'test/*Spec.js'
15 | ],
16 | junitReporter: {
17 | outputFile: 'test_out/unit.xml',
18 | suite: 'unit'
19 | },
20 | frameworks: ['jasmine']
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/karma.min.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config) {
2 | config.set({
3 | autoWatch: false,
4 | singleRun: true,
5 | logLevel: config.LOG_INFO,
6 | logColors: true,
7 | browsers: ['Chrome'],
8 | files: [
9 | 'node_modules/angular/angular.js',
10 | 'node_modules/angular-cookies/angular-cookies.js',
11 | 'node_modules/angular-mocks/angular-mocks.js',
12 | {pattern: 'node_modules/angular-i18n/*.js', included: false, served: true},
13 | '*.min.js',
14 | 'test/*Spec.js'
15 | ],
16 | junitReporter: {
17 | outputFile: 'test_out/unit.xml',
18 | suite: 'unit'
19 | },
20 | frameworks: ['jasmine']
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2013 Lucas Galfasó
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-dynamic-locale",
3 | "version": "0.1.23",
4 | "description": "A minimal module that adds the ability to dynamically change the locale",
5 | "license": "MIT License, http://www.opensource.org/licenses/MIT",
6 | "devDependencies": {
7 | "angular": "1.3.0",
8 | "angular-cookies": "1.3.0",
9 | "angular-i18n": "1.3.0",
10 | "angular-mocks": "1.3.0",
11 | "grunt": "^0.4.1",
12 | "grunt-bump": "0.0.13",
13 | "grunt-contrib-clean": "0.5.0",
14 | "grunt-contrib-concat": "0.3.0",
15 | "grunt-contrib-copy": "^0.4.1",
16 | "grunt-contrib-jshint": "^0.8.0",
17 | "grunt-contrib-uglify": "^0.5.0",
18 | "grunt-contrib-watch": "^0.5.1",
19 | "grunt-jscs": "^0.8.1",
20 | "grunt-karma": "^0.8.2",
21 | "grunt-npm": "0.0.2",
22 | "karma": "^0.12.1",
23 | "karma-chrome-launcher": "0.1.2",
24 | "karma-firefox-launcher": "0.1.3",
25 | "karma-jasmine": "0.2.2",
26 | "karma-phantomjs-launcher": "0.1.2"
27 | },
28 | "main": "./src/tmhDynamicLocale.js",
29 | "scripts": {
30 | "test": "grunt karma:travis"
31 | },
32 | "repository": {
33 | "type": "git",
34 | "url": "git://github.com/lgalfaso/angular-dynamic-locale.git"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | 'use strict';
3 |
4 | module.exports = function(grunt) {
5 | //grunt plugins
6 | grunt.loadNpmTasks('grunt-contrib-clean');
7 | grunt.loadNpmTasks('grunt-contrib-copy');
8 | grunt.loadNpmTasks('grunt-contrib-jshint');
9 | grunt.loadNpmTasks('grunt-jscs');
10 | grunt.loadNpmTasks('grunt-karma');
11 | grunt.loadNpmTasks('grunt-bump');
12 | grunt.loadNpmTasks('grunt-npm');
13 | grunt.loadNpmTasks('grunt-contrib-uglify');
14 |
15 | grunt.initConfig({
16 | jshint: {
17 | all: ['Gruntfile.js', 'src/*.js', 'test/*.js']
18 | },
19 | jscs: {
20 | src: ['src/**/*.js', 'test/**/*.js'],
21 | options: {
22 | config: ".jscs.json"
23 | }
24 | },
25 | karma: {
26 | unit: { configFile: 'karma.conf.js' },
27 | 'unit.min': {
28 | configFile: 'karma.min.conf.js'
29 | },
30 | autotest: {
31 | configFile: 'karma.conf.js',
32 | autoWatch: true,
33 | singleRun: false
34 | },
35 | travis: {
36 | configFile: 'karma.conf.js',
37 | reporters: 'dots',
38 | browsers: ['PhantomJS']
39 | }
40 | },
41 | uglify: {
42 | all: {
43 | files: {
44 | 'tmhDynamicLocale.min.js': ['src/*.js']
45 | },
46 | options: {
47 | sourceMap: true
48 | }
49 | }
50 | },
51 | bump: {
52 | options: {
53 | files: ['package.json', 'bower.json'],
54 | commitFiles: ['package.json', 'bower.json'],
55 | tagName: '%VERSION%',
56 | pushTo: 'origin'
57 | }
58 | },
59 | 'npm-publish': {
60 | options: {
61 | requires: ['jshint', 'karma:unit', 'bump'],
62 | abortIfDirty: true
63 | }
64 | }
65 | });
66 | grunt.registerTask('release', ['jshint', 'jscs', 'karma:unit', 'uglify:all', 'karma:unit.min', 'bump', 'publish']);
67 | };
68 | }());
69 |
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Angular Dynamic Locale
2 |
3 | ***
4 |
5 | ## Usage
6 |
7 | ### Requirements
8 |
9 | * **AngularJS v1.0.7+** is currently required.
10 |
11 | ### Changing the locale
12 |
13 | This module defines two services, these are `tmhDynamicLocale` and
14 | `tmhDynamicLocaleCache`.
15 |
16 | The service `tmhDynamicLocale` provides has one method `set(newLocale)` to
17 | change the locale.
18 |
19 | ```javascript
20 | tmhDynamicLocale.set('it');
21 | ```
22 |
23 | Keep in mind that the locale will be changed asynchronously
24 |
25 |
26 | After the locale is changed, the event `'$localeChangeSuccess'` will be
27 | triggered.
28 |
29 | Calling `tmhDynamicLocale.set` will return a promise that will be resolved
30 | when the locale is loaded and will resolve to the new locale.
31 |
32 | The service `tmhDynamicLocaleCache` is a `$cache` of all the loaded locales,
33 | where the key is the locale id and the value is the locale object.
34 |
35 |
36 | This module expects for the angular locales to be present at
37 | `angular/i18n/angular-locale_{{locale}}.js`.
38 | If the locales are at another URL, this can be changed at
39 | `tmhDynamicLocaleProvider` using `localeLocationPattern(string)`.
40 |
41 |
42 | It is possible to specify a storage location for the locale using
43 | `tmhDynamicLocaleProvider.useStorage(storageName)`, the name of the
44 | storage must follow the same signature as `$cookieStore`. The default
45 | storage location is to use a `$cache`, this default storage is not persistent.
46 |
47 | It is possible to ask the storage to be `$cookieStore` using the shortcut
48 | `tmhDynamicLocaleProvider.useCookieStorage()`, internally this is
49 | exactly as performing `tmhDynamicLocaleProvider.useStorage('$cookieStore')`
50 |
51 | ## Installation
52 |
53 | Add the module to your dependencies
54 |
55 | ```javascript
56 | angular.module('myApp', ['tmh.dynamicLocale', ...])
57 | ```
58 |
59 |
60 | ## Development
61 |
62 | ### Requirements
63 |
64 | 0. Install [Node.js](http://nodejs.org/) and NPM (should come with)
65 |
66 | 1. Install global dependencies `grunt-cli` and `bower`:
67 |
68 | ```bash
69 | $ npm install -g grunt-cli bower
70 | ```
71 |
72 | 2. Install local dependencies:
73 |
74 | ```bash
75 | $ npm install
76 | ```
77 |
78 | ### Running the tests
79 |
80 | ```bash
81 | $ grunt karma:unit
82 | ```
83 | to run the test once
84 |
85 | or
86 |
87 | ```bash
88 | $ grunt karma:autotest
89 | ```
90 | to run the tests continuously
91 |
92 |
--------------------------------------------------------------------------------
/tmhDynamicLocale.min.js:
--------------------------------------------------------------------------------
1 | !function(){"use strict";angular.module("tmh.dynamicLocale",[]).config(["$provide",function(a){function b(a){return a.$stateful=!0,a}a.decorator("dateFilter",["$delegate",b]),a.decorator("numberFilter",["$delegate",b]),a.decorator("currencyFilter",["$delegate",b])}]).constant("tmhDynamicLocale.STORAGE_KEY","tmhDynamicLocale.locale").provider("tmhDynamicLocale",["tmhDynamicLocale.STORAGE_KEY",function(a){function b(a,b,c,d){var e=document.createElement("script"),f=document.getElementsByTagName("body")[0],g=!1;e.type="text/javascript",e.readyState?e.onreadystatechange=function(){("complete"===e.readyState||"loaded"===e.readyState)&&(e.onreadystatechange=null,d(function(){g||(g=!0,f.removeChild(e),b())},30,!1))}:(e.onload=function(){g||(g=!0,f.removeChild(e),b())},e.onerror=function(){g||(g=!0,f.removeChild(e),c())}),e.src=a,e.async=!1,f.appendChild(e)}function c(a,c,d,g,h,k,l){function m(a,b){f===d&&(angular.forEach(a,function(c,d){b[d]?angular.isArray(b[d])&&(a[d].length=b[d].length):delete a[d]}),angular.forEach(b,function(c,d){angular.isArray(b[d])||angular.isObject(b[d])?(a[d]||(a[d]=angular.isArray(b[d])?[]:{}),m(a[d],b[d])):a[d]=b[d]}))}if(j[d])return j[d];var n,o=h.defer();return d===f?o.resolve(c):(n=k.get(d))?(f=d,g.$evalAsync(function(){m(c,n),g.$broadcast("$localeChangeSuccess",d,c),e.put(i,d),o.resolve(c)})):(f=d,j[d]=o.promise,b(a,function(){var a=angular.injector(["ngLocale"]),b=a.get("$locale");m(c,b),k.put(d,b),delete j[d],g.$apply(function(){g.$broadcast("$localeChangeSuccess",d,c),e.put(i,d),o.resolve(c)})},function(){delete j[d],g.$apply(function(){f===d&&(f=c.id),g.$broadcast("$localeChangeError",d),o.reject(d)})},l)),o.promise}var d,e,f,g="angular/i18n/angular-locale_{{locale}}.js",h="tmhDynamicLocaleStorageCache",i=a,j={};this.localeLocationPattern=function(a){return a?(g=a,this):g},this.useStorage=function(a){h=a},this.useCookieStorage=function(){this.useStorage("$cookieStore")},this.defaultLocale=function(a){d=a},this.storageKey=function(a){return a?(i=a,this):i},this.$get=["$rootScope","$injector","$interpolate","$locale","$q","tmhDynamicLocaleCache","$timeout",function(a,b,j,k,l,m,n){var o=j(g);return e=b.get(h),a.$evalAsync(function(){var b;(b=e.get(i)||d)&&c(o({locale:b}),k,b,a,l,m,n)}),{set:function(b){return c(o({locale:b}),k,b,a,l,m,n)},get:function(){return f}}}]}]).provider("tmhDynamicLocaleCache",function(){this.$get=["$cacheFactory",function(a){return a("tmh.dynamicLocales")}]}).provider("tmhDynamicLocaleStorageCache",function(){this.$get=["$cacheFactory",function(a){return a("tmh.dynamicLocales.store")}]}).run(["tmhDynamicLocale",angular.noop])}(window);
2 | //# sourceMappingURL=tmhDynamicLocale.min.js.map
--------------------------------------------------------------------------------
/tmhDynamicLocale.min.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"tmhDynamicLocale.min.js","sources":["src/tmhDynamicLocale.js"],"names":["angular","module","config","$provide","makeStateful","$delegate","$stateful","decorator","constant","provider","STORAGE_KEY","loadScript","url","callback","errorCallback","$timeout","script","document","createElement","body","getElementsByTagName","removed","type","readyState","onreadystatechange","removeChild","onload","onerror","src","async","appendChild","loadLocale","localeUrl","$locale","localeId","$rootScope","$q","localeCache","overrideValues","oldObject","newObject","activeLocale","forEach","value","key","isArray","length","isObject","promiseCache","cachedLocale","deferred","defer","resolve","get","$evalAsync","$broadcast","storage","put","storageKey","promise","localInjector","injector","externalLocale","$apply","id","reject","defaultLocale","localeLocationPattern","storageFactory","this","useStorage","storageName","useCookieStorage","$get","$injector","interpolate","locale","tmhDynamicLocaleCache","localeLocation","initialLocale","set","$cacheFactory","run","noop","window"],"mappings":"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"}
--------------------------------------------------------------------------------
/src/tmhDynamicLocale.js:
--------------------------------------------------------------------------------
1 | (function(window) {
2 | 'use strict';
3 | angular.module('tmh.dynamicLocale', []).config(['$provide', function ($provide) {
4 | function makeStateful($delegate) {
5 | $delegate.$stateful = true;
6 | return $delegate;
7 | }
8 |
9 | $provide.decorator('dateFilter', ['$delegate', makeStateful]);
10 | $provide.decorator('numberFilter', ['$delegate', makeStateful]);
11 | $provide.decorator('currencyFilter', ['$delegate', makeStateful]);
12 |
13 | }])
14 | .constant('tmhDynamicLocale.STORAGE_KEY', 'tmhDynamicLocale.locale')
15 | .provider('tmhDynamicLocale', ['tmhDynamicLocale.STORAGE_KEY', function(STORAGE_KEY) {
16 |
17 | var defaultLocale,
18 | localeLocationPattern = 'angular/i18n/angular-locale_{{locale}}.js',
19 | storageFactory = 'tmhDynamicLocaleStorageCache',
20 | storage,
21 | storageKey = STORAGE_KEY,
22 | promiseCache = {},
23 | activeLocale;
24 |
25 | /**
26 | * Loads a script asynchronously
27 | *
28 | * @param {string} url The url for the script
29 | @ @param {function) callback A function to be called once the script is loaded
30 | */
31 | function loadScript(url, callback, errorCallback, $timeout) {
32 | var script = document.createElement('script'),
33 | body = document.getElementsByTagName('body')[0],
34 | removed = false;
35 |
36 | script.type = 'text/javascript';
37 | if (script.readyState) { // IE
38 | script.onreadystatechange = function () {
39 | if (script.readyState === 'complete' ||
40 | script.readyState === 'loaded') {
41 | script.onreadystatechange = null;
42 | $timeout(
43 | function () {
44 | if (removed) return;
45 | removed = true;
46 | body.removeChild(script);
47 | callback();
48 | }, 30, false);
49 | }
50 | };
51 | } else { // Others
52 | script.onload = function () {
53 | if (removed) return;
54 | removed = true;
55 | body.removeChild(script);
56 | callback();
57 | };
58 | script.onerror = function () {
59 | if (removed) return;
60 | removed = true;
61 | body.removeChild(script);
62 | errorCallback();
63 | };
64 | }
65 | script.src = url;
66 | script.async = false;
67 | body.appendChild(script);
68 | }
69 |
70 | /**
71 | * Loads a locale and replaces the properties from the current locale with the new locale information
72 | *
73 | * @param localeUrl The path to the new locale
74 | * @param $locale The locale at the curent scope
75 | */
76 | function loadLocale(localeUrl, $locale, localeId, $rootScope, $q, localeCache, $timeout) {
77 |
78 | function overrideValues(oldObject, newObject) {
79 | if (activeLocale !== localeId) {
80 | return;
81 | }
82 | angular.forEach(oldObject, function(value, key) {
83 | if (!newObject[key]) {
84 | delete oldObject[key];
85 | } else if (angular.isArray(newObject[key])) {
86 | oldObject[key].length = newObject[key].length;
87 | }
88 | });
89 | angular.forEach(newObject, function(value, key) {
90 | if (angular.isArray(newObject[key]) || angular.isObject(newObject[key])) {
91 | if (!oldObject[key]) {
92 | oldObject[key] = angular.isArray(newObject[key]) ? [] : {};
93 | }
94 | overrideValues(oldObject[key], newObject[key]);
95 | } else {
96 | oldObject[key] = newObject[key];
97 | }
98 | });
99 | }
100 |
101 |
102 | if (promiseCache[localeId]) return promiseCache[localeId];
103 |
104 | var cachedLocale,
105 | deferred = $q.defer();
106 | if (localeId === activeLocale) {
107 | deferred.resolve($locale);
108 | } else if ((cachedLocale = localeCache.get(localeId))) {
109 | activeLocale = localeId;
110 | $rootScope.$evalAsync(function() {
111 | overrideValues($locale, cachedLocale);
112 | $rootScope.$broadcast('$localeChangeSuccess', localeId, $locale);
113 | storage.put(storageKey, localeId);
114 | deferred.resolve($locale);
115 | });
116 | } else {
117 | activeLocale = localeId;
118 | promiseCache[localeId] = deferred.promise;
119 | loadScript(localeUrl, function () {
120 | // Create a new injector with the new locale
121 | var localInjector = angular.injector(['ngLocale']),
122 | externalLocale = localInjector.get('$locale');
123 |
124 | overrideValues($locale, externalLocale);
125 | localeCache.put(localeId, externalLocale);
126 | delete promiseCache[localeId];
127 |
128 | $rootScope.$apply(function () {
129 | $rootScope.$broadcast('$localeChangeSuccess', localeId, $locale);
130 | storage.put(storageKey, localeId);
131 | deferred.resolve($locale);
132 | });
133 | }, function () {
134 | delete promiseCache[localeId];
135 |
136 | $rootScope.$apply(function () {
137 | if (activeLocale === localeId) activeLocale = $locale.id;
138 | $rootScope.$broadcast('$localeChangeError', localeId);
139 | deferred.reject(localeId);
140 | });
141 | }, $timeout);
142 | }
143 | return deferred.promise;
144 | }
145 |
146 | this.localeLocationPattern = function(value) {
147 | if (value) {
148 | localeLocationPattern = value;
149 | return this;
150 | } else {
151 | return localeLocationPattern;
152 | }
153 | };
154 |
155 | this.useStorage = function(storageName) {
156 | storageFactory = storageName;
157 | };
158 |
159 | this.useCookieStorage = function() {
160 | this.useStorage('$cookieStore');
161 | };
162 |
163 | this.defaultLocale = function (value) {
164 | defaultLocale = value;
165 | };
166 |
167 | this.storageKey = function (value) {
168 | if (value) {
169 | storageKey = value;
170 | return this;
171 | } else {
172 | return storageKey;
173 | }
174 | };
175 |
176 | this.$get = ['$rootScope', '$injector', '$interpolate', '$locale', '$q', 'tmhDynamicLocaleCache', '$timeout', function($rootScope, $injector, interpolate, locale, $q, tmhDynamicLocaleCache, $timeout) {
177 | var localeLocation = interpolate(localeLocationPattern);
178 |
179 | storage = $injector.get(storageFactory);
180 | $rootScope.$evalAsync(function () {
181 | var initialLocale;
182 | if ((initialLocale = (storage.get(storageKey) || defaultLocale))) {
183 | loadLocale(localeLocation({locale: initialLocale}), locale, initialLocale, $rootScope, $q, tmhDynamicLocaleCache, $timeout);
184 | }
185 | });
186 | return {
187 | /**
188 | * @ngdoc method
189 | * @description
190 | * @param {string=} value Sets the locale to the new locale. Changing the locale will trigger
191 | * a background task that will retrieve the new locale and configure the current $locale
192 | * instance with the information from the new locale
193 | */
194 | set: function(value) {
195 | return loadLocale(localeLocation({locale: value}), locale, value, $rootScope, $q, tmhDynamicLocaleCache, $timeout);
196 | },
197 | /**
198 | * @ngdoc method
199 | * @description Returns the configured locale
200 | */
201 | get: function() {
202 | return activeLocale;
203 | }
204 | };
205 | }];
206 | }]).provider('tmhDynamicLocaleCache', function() {
207 | this.$get = ['$cacheFactory', function($cacheFactory) {
208 | return $cacheFactory('tmh.dynamicLocales');
209 | }];
210 | }).provider('tmhDynamicLocaleStorageCache', function() {
211 | this.$get = ['$cacheFactory', function($cacheFactory) {
212 | return $cacheFactory('tmh.dynamicLocales.store');
213 | }];
214 | }).run(['tmhDynamicLocale', angular.noop]);
215 | }(window));
216 |
--------------------------------------------------------------------------------
/test/tmhDynamicLocaleSpec.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | 'use strict';
3 |
4 | // Minimal implementation to mock what was removed from Jasmine 1.x
5 | function createAsync(doneFn) {
6 | function Job() {
7 | this.next = [];
8 | }
9 | Job.prototype.done = function () {
10 | return this.runs(doneFn);
11 | };
12 | Job.prototype.runs = function (fn) {
13 | var newJob = new Job();
14 | this.next.push(function () {
15 | fn();
16 | newJob.start();
17 | });
18 | return newJob;
19 | };
20 | Job.prototype.waitsFor = function (fn, error, timeout) {
21 | var newJob = new Job();
22 | timeout = timeout || 5000;
23 | this.next.push(function () {
24 | var counter = 0,
25 | intervalId = window.setInterval(function () {
26 | if (fn()) {
27 | window.clearInterval(intervalId);
28 | newJob.start();
29 | }
30 | counter += 5;
31 | if (counter > timeout) {
32 | window.clearInterval(intervalId);
33 | throw new Error(error);
34 | }
35 | }, 5);
36 | });
37 | return newJob;
38 | };
39 | Job.prototype.start = function () {
40 | var i;
41 | for (i = 0; i < this.next.length; i += 1) {
42 | this.next[i]();
43 | }
44 | };
45 | return new Job();
46 | }
47 |
48 | describe('dynamicLocale', function() {
49 | beforeEach(module('tmh.dynamicLocale'));
50 | beforeEach(module(function(tmhDynamicLocaleProvider) {
51 | tmhDynamicLocaleProvider.localeLocationPattern('/base/node_modules/angular-i18n/angular-locale_{{locale}}.js');
52 | }));
53 |
54 | afterEach(function (done) {
55 | inject(function($locale, $timeout, tmhDynamicLocale) {
56 | var job = createAsync(done);
57 | job
58 | .runs(function() {
59 | tmhDynamicLocale.set('en-us');
60 | })
61 | .waitsFor(function() {
62 | $timeout.flush(50);
63 | return $locale.id === 'en-us';
64 | }, 'locale not reverted', 2000)
65 | .done();
66 | job.start();
67 | });
68 | });
69 |
70 | it('should (eventually) be able to change the locale', function(done) {
71 | inject(function($locale, $timeout, tmhDynamicLocale) {
72 | var job = createAsync(done);
73 | job
74 | .runs(function() {
75 | tmhDynamicLocale.set('es');
76 | })
77 | .waitsFor(function() {
78 | $timeout.flush(50);
79 | return $locale.id === 'es';
80 | }, 'locale not updated', 2000)
81 | .runs(function() {
82 | expect($locale.id).toBe('es');
83 | expect($locale.DATETIME_FORMATS.DAY["0"]).toBe("domingo");
84 | })
85 | .done();
86 | job.start();
87 | });
88 | });
89 |
90 | it('should trigger an event when there it changes the locale', function(done) {
91 | inject(function($timeout, $locale, tmhDynamicLocale, $rootScope) {
92 | var callback = jasmine.createSpy();
93 | var job = createAsync(done);
94 | job
95 | .runs(function() {
96 | $rootScope.$apply();
97 | $rootScope.$on('$localeChangeSuccess', callback);
98 | tmhDynamicLocale.set('es');
99 | expect(callback.calls.count()).toBe(0);
100 | })
101 | .waitsFor(function() {
102 | $timeout.flush(50);
103 | return $locale.id === 'es';
104 | }, 'locale not updated', 2000)
105 | .runs(function() {
106 | expect(callback.calls.count()).toBe(1);
107 | expect(callback.calls.argsFor(0)[1]).toEqual('es');
108 | expect(callback.calls.argsFor(0)[2]).toEqual($locale);
109 | })
110 | .done();
111 | job.start();
112 | });
113 | });
114 |
115 | it('should trigger a failure even when the locale change fail', function(done) {
116 | inject(function($timeout, $locale, tmhDynamicLocale, $rootScope) {
117 | var job = createAsync(done);
118 | var callback = jasmine.createSpy();
119 |
120 | job
121 | .runs(function() {
122 | $rootScope.$apply();
123 | $rootScope.$on('$localeChangeError', callback);
124 | tmhDynamicLocale.set('invalidLocale');
125 | expect(callback.calls.count()).toBe(0);
126 | })
127 | .waitsFor(function() {
128 | $timeout.flush(50);
129 | return callback.calls.count() !== 0;
130 | }, 'error not generated', 2000)
131 | .runs(function() {
132 | expect(callback.calls.count()).toBe(1);
133 | expect(callback.calls.argsFor(0)[1]).toEqual('invalidLocale');
134 | })
135 | .done();
136 | job.start();
137 | });
138 | });
139 |
140 | it('should return a promise that has the new locale', function(done) {
141 | inject(function($timeout, $locale, tmhDynamicLocale, $rootScope) {
142 | var job = createAsync(done);
143 | var callback = jasmine.createSpy();
144 |
145 | job
146 | .runs(function() {
147 | tmhDynamicLocale.set('es').then(callback);
148 | expect(callback.calls.count()).toBe(0);
149 | })
150 | .waitsFor(function() {
151 | $timeout.flush(50);
152 | return callback.calls.count() !== 0;
153 | }, 'locale not updated', 2000)
154 | .runs(function() {
155 | expect(callback.calls.argsFor(0)[0].id).toEqual('es');
156 | expect(callback.calls.argsFor(0)[0]).toEqual($locale);
157 | tmhDynamicLocale.set('it');
158 | })
159 | .waitsFor(function() {
160 | $timeout.flush(50);
161 | return $locale.id === 'it';
162 | }, 'locale not updated', 2000)
163 | .runs(function() {
164 | tmhDynamicLocale.set('es').then(callback);
165 | expect(callback.calls.count()).toBe(1);
166 | $rootScope.$apply();
167 | expect(callback.calls.count()).toBe(2);
168 | expect(callback.calls.argsFor(1)[0].id).toBe('es');
169 | expect(callback.calls.argsFor(1)[0]).toBe($locale);
170 | })
171 | .done();
172 | job.start();
173 | });
174 | });
175 |
176 | it('should reject the returned promise if it fails to load the locale', function(done) {
177 | inject(function($timeout, $locale, tmhDynamicLocale, $rootScope) {
178 | var callback = jasmine.createSpy();
179 | var errorCallback = jasmine.createSpy();
180 | var job = createAsync(done);
181 |
182 | job
183 | .runs(function() {
184 | tmhDynamicLocale.set('invalidLocale').then(callback, errorCallback);
185 | })
186 | .waitsFor(function() {
187 | $timeout.flush(50);
188 | return errorCallback.calls.count();
189 | }, 'promise not rejected', 2000)
190 | .runs(function() {
191 | expect(callback.calls.count()).toBe(0);
192 | expect(errorCallback.calls.count()).toBe(1);
193 | expect(errorCallback.calls.argsFor(0)[0]).toBe('invalidLocale');
194 | expect($locale.id).toBe('en-us');
195 | })
196 | .done();
197 | job.start();
198 | });
199 | });
200 |
201 | it('should be possible to retrieve the locale to be', function(done) {
202 | inject(function($timeout, $locale, tmhDynamicLocale, $rootScope, $compile) {
203 | var job = createAsync(done);
204 |
205 | job
206 | .runs(function() {
207 | tmhDynamicLocale.set('es');
208 | expect(tmhDynamicLocale.get()).toBe('es');
209 | })
210 | .waitsFor(function() {
211 | $timeout.flush(50);
212 | return $locale.id === 'es';
213 | }, 'locale not updated', 2000)
214 | .runs(function() {
215 | expect(tmhDynamicLocale.get()).toBe('es');
216 | })
217 | .done();
218 | job.start();
219 | });
220 | });
221 |
222 | it('should revert the configured locale when the new locale does not exist', function(done) {
223 | inject(function($timeout, $locale, tmhDynamicLocale, $rootScope) {
224 | var job = createAsync(done);
225 | var errorCallback = jasmine.createSpy();
226 |
227 | job
228 | .runs(function() {
229 | tmhDynamicLocale.set('es');
230 | })
231 | .waitsFor(function() {
232 | $timeout.flush(50);
233 | return $locale.id === 'es';
234 | }, 'locale not updated', 2000)
235 | .runs(function() {
236 | tmhDynamicLocale.set('invalidLocale').then(undefined, errorCallback);
237 | expect(tmhDynamicLocale.get()).toBe('invalidLocale');
238 | })
239 | .waitsFor(function() {
240 | $timeout.flush(50);
241 | return errorCallback.calls.count();
242 | }, 'promise not rejected', 2000)
243 | .runs(function() {
244 | expect(tmhDynamicLocale.get()).toBe('es');
245 | })
246 | .done();
247 | job.start();
248 | });
249 | });
250 |
251 | it('should change the already formatted numbers in the page', function(done) {
252 | inject(function($timeout, $locale, tmhDynamicLocale, $rootScope, $compile) {
253 | var job = createAsync(done);
254 | var element = null;
255 |
256 | job
257 | .runs(function() {
258 | element = $compile('{{val | number}}')($rootScope);
259 |
260 | $rootScope.val = 1234.5678;
261 | $rootScope.$apply();
262 | expect(element.text()).toBe('1,234.568');
263 |
264 | tmhDynamicLocale.set('es');
265 | })
266 | .waitsFor(function() {
267 | $timeout.flush(50);
268 | return $locale.id === 'es';
269 | }, 'locale not updated', 2000)
270 | .runs(function() {
271 | expect(element.text()).toBe('1.234,568');
272 | })
273 | .done();
274 | job.start();
275 | });
276 | });
277 |
278 | it('should keep already loaded locales at tmhDynamicLocaleCache', function(done) {
279 | inject(function($timeout, $locale, tmhDynamicLocale, tmhDynamicLocaleCache, $rootScope) {
280 | var job = createAsync(done);
281 | var callback = jasmine.createSpy();
282 | var esLocale = null;
283 |
284 | job
285 | .runs(function() {
286 | expect(tmhDynamicLocaleCache.info().size).toBe(0);
287 | tmhDynamicLocale.set('es');
288 | expect(tmhDynamicLocaleCache.info().size).toBe(0);
289 | })
290 | .waitsFor(function() {
291 | $timeout.flush(50);
292 | return $locale.id === 'es';
293 | }, 'locale not updated', 2000)
294 | .runs(function() {
295 | expect(tmhDynamicLocaleCache.info().size).toBe(1);
296 | expect(tmhDynamicLocaleCache.get('es')).toEqual($locale);
297 | esLocale = angular.copy($locale);
298 | tmhDynamicLocale.set('it');
299 | })
300 | .waitsFor(function() {
301 | $timeout.flush(50);
302 | return $locale.id === 'it';
303 | }, 'locale not updated', 2000)
304 | .runs(function() {
305 | expect(tmhDynamicLocaleCache.info().size).toBe(2);
306 | expect(tmhDynamicLocaleCache.get('es')).toEqual(esLocale);
307 | expect(tmhDynamicLocaleCache.get('it')).toEqual($locale);
308 | })
309 | .done();
310 | job.start();
311 | });
312 | });
313 |
314 | it('should use the cache when possible', function(done) {
315 | inject(function($timeout, $locale, tmhDynamicLocale, tmhDynamicLocaleCache, $rootScope) {
316 | var job = createAsync(done);
317 | var callback = jasmine.createSpy();
318 |
319 | job
320 | .runs(function() {
321 | tmhDynamicLocale.set('es');
322 | })
323 | .waitsFor(function() {
324 | $timeout.flush(50);
325 | return $locale.id === 'es';
326 | }, 'locale not updated', 2000)
327 | .runs(function() {
328 | tmhDynamicLocale.set('it');
329 | })
330 | .waitsFor(function() {
331 | $timeout.flush(50);
332 | return $locale.id === 'it';
333 | }, 'locale not updated', 2000)
334 | .runs(function() {
335 | tmhDynamicLocaleCache.get('es').DATETIME_FORMATS.DAY["0"] = "Domingo";
336 | $rootScope.$on('$localeChangeSuccess', callback);
337 | tmhDynamicLocale.set('es');
338 | // Changing the locale should be done async even when this is done from the cache
339 | expect(callback.calls.count()).toBe(0);
340 | expect($locale.id).toBe('it');
341 | $rootScope.$apply();
342 | expect($locale.id).toBe('es');
343 | expect($locale.DATETIME_FORMATS.DAY["0"]).toBe("Domingo");
344 | expect(callback.calls.count()).toBe(1);
345 | })
346 | .done();
347 | job.start();
348 | });
349 | });
350 |
351 | it('should do a deep copy of the locale elements', function(done) {
352 | inject(function($timeout, $locale, tmhDynamicLocale, tmhDynamicLocaleCache, $rootScope) {
353 | var job = createAsync(done);
354 |
355 | job
356 | .runs(function() {
357 | tmhDynamicLocale.set('es');
358 | })
359 | .waitsFor(function() {
360 | $timeout.flush(50);
361 | return $locale.id === 'es';
362 | }, 'locale not updated', 2000)
363 | .runs(function() {
364 | $locale.DATETIME_FORMATS.DAY["0"] = "XXX";
365 | expect($locale.DATETIME_FORMATS.DAY["0"]).not.toBe(tmhDynamicLocaleCache.get('es').DATETIME_FORMATS.DAY["0"]);
366 | })
367 | .done();
368 | job.start();
369 | });
370 | });
371 |
372 | it('should be able to handle locales with extra elements', function(done) {
373 | inject(function($timeout, $locale, tmhDynamicLocale, tmhDynamicLocaleCache, $rootScope) {
374 | var job = createAsync(done);
375 | var weirdLocale;
376 |
377 | job
378 | .runs(function() {
379 | tmhDynamicLocale.set('es');
380 | })
381 | .waitsFor(function() {
382 | $timeout.flush(50);
383 | return $locale.id === 'es';
384 | }, 'locale not updated', 2000)
385 | .runs(function() {
386 | weirdLocale = angular.copy($locale);
387 | weirdLocale.id = "xx";
388 | weirdLocale.EXTRA_PARAMETER = {foo: "FOO"};
389 | weirdLocale.DATETIME_FORMATS.DAY["7"] = "One More Day";
390 | tmhDynamicLocaleCache.put('xx', angular.copy(weirdLocale));
391 | tmhDynamicLocale.set('xx');
392 | })
393 | .waitsFor(function() {
394 | $timeout.flush(50);
395 | return $locale.id === 'xx';
396 | }, 'locale not updated', 2000)
397 | .runs(function() {
398 | expect($locale).toEqual(weirdLocale);
399 | expect($locale.EXTRA_PARAMETER).toEqual({foo: "FOO"});
400 | tmhDynamicLocale.set('es');
401 | })
402 | .waitsFor(function() {
403 | $timeout.flush(50);
404 | return $locale.id === 'es';
405 | }, 'locale not updated', 2000)
406 | .runs(function() {
407 | expect($locale.EXTRA_PARAMETER).toBeUndefined();
408 | expect($locale.DATETIME_FORMATS.DAY["7"]).toBeUndefined();
409 | expect($locale.DATETIME_FORMATS.DAY.length).toBe(7);
410 | })
411 | .done();
412 | job.start();
413 | });
414 | });
415 |
416 | describe('having a default locale', function() {
417 | beforeEach(module(function(tmhDynamicLocaleProvider) {
418 | tmhDynamicLocaleProvider.defaultLocale('it');
419 | }));
420 | it('should set the locale to the default locale', function(done) {
421 | inject(function($timeout, $locale, $rootScope) {
422 | var job = createAsync(done);
423 |
424 | job
425 | .runs(function() {
426 | expect($locale.id).toBe('en-us');
427 | $rootScope.$apply();
428 | })
429 | .waitsFor(function() {
430 | $timeout.flush(50);
431 | return $locale.id === 'it';
432 | }, 'locale not updated', 2000)
433 | .runs(function() {
434 | expect($locale.id).toBe('it');
435 | })
436 | .done();
437 | job.start();
438 | });
439 | });
440 | });
441 |
442 | describe('having a cookie storage', function () {
443 | beforeEach(module('ngCookies'));
444 | beforeEach(module(function(tmhDynamicLocaleProvider) {
445 | tmhDynamicLocaleProvider.useCookieStorage();
446 | }));
447 |
448 | it('should store the change on the cookie store', function(done) {
449 | inject(function ($timeout, $locale, $cookieStore, tmhDynamicLocale) {
450 | var job = createAsync(done);
451 |
452 | job
453 | .runs(function() {
454 | tmhDynamicLocale.set('es');
455 | expect($cookieStore.get('tmhDynamicLocale.locale')).toBe(undefined);
456 | })
457 | .waitsFor(function() {
458 | $timeout.flush(50);
459 | return $locale.id === 'es';
460 | }, 'locale not updated', 2000)
461 | .runs(function() {
462 | expect($cookieStore.get('tmhDynamicLocale.locale')).toBe('es');
463 | })
464 | .done();
465 | job.start();
466 | });
467 | });
468 | describe('reading the locale at initialization', function () {
469 | beforeEach(inject(function ($cookieStore, $rootScope) {
470 | $cookieStore.put('tmhDynamicLocale.locale', 'it');
471 | $rootScope.$apply();
472 | }));
473 |
474 | it('should load the locale on initialization', function(done) {
475 | inject(function ($timeout, $locale, $rootScope) {
476 | var job = createAsync(done);
477 |
478 | job
479 | .runs(function() {
480 | expect($locale.id).toBe('en-us');
481 | })
482 | .waitsFor(function() {
483 | $timeout.flush(50);
484 | return $locale.id === 'it';
485 | }, 'locale not updated', 2000)
486 | .runs(function() {
487 | expect($locale.id).toBe('it');
488 | })
489 | .done();
490 | job.start();
491 | });
492 | });
493 | });
494 | describe('and having a default language', function () {
495 | beforeEach(module(function(tmhDynamicLocaleProvider) {
496 | tmhDynamicLocaleProvider.defaultLocale('es');
497 | }));
498 | beforeEach(inject(function ($cookieStore, $rootScope) {
499 | $cookieStore.put('tmhDynamicLocale.locale', 'it');
500 | $rootScope.$apply();
501 | }));
502 |
503 | it('should load the locale on initialization', function(done) {
504 | inject(function ($timeout, $locale, $rootScope) {
505 | var job = createAsync(done);
506 |
507 | job
508 | .runs(function() {
509 | expect($locale.id).toBe('en-us');
510 | })
511 | .waitsFor(function() {
512 | $timeout.flush(50);
513 | return $locale.id === 'it';
514 | }, 'locale not updated', 2000)
515 | .runs(function() {
516 | expect($locale.id).toBe('it');
517 | })
518 | .done();
519 | job.start();
520 | });
521 | });
522 | });
523 | describe('and changing the name of the storageKey', function () {
524 | beforeEach(module(function(tmhDynamicLocaleProvider) {
525 | tmhDynamicLocaleProvider.storageKey('customStorageKeyName');
526 | }));
527 |
528 | it('should change the name of the storageKey', function(done) {
529 | inject(function ($timeout, $locale, $cookieStore, tmhDynamicLocale) {
530 | var job = createAsync(done);
531 |
532 | job
533 | .runs(function() {
534 | tmhDynamicLocale.set('es');
535 | expect($cookieStore.get('customStorageKeyName')).toBe(undefined);
536 | expect($cookieStore.get('tmhDynamicLocale.locale')).toBe(undefined);
537 | })
538 | .waitsFor(function() {
539 | $timeout.flush(50);
540 | return $locale.id === 'es';
541 | }, 'locale not updated', 2000)
542 | .runs(function() {
543 | expect($cookieStore.get('tmhDynamicLocale.locale')).toBe(undefined);
544 | expect($cookieStore.get('customStorageKeyName')).toBe('es');
545 | })
546 | .done();
547 | job.start();
548 | });
549 | });
550 | });
551 | });
552 |
553 | describe('loading locales using