From 0a0730dccc0415c0f3fca1ac3ad9a1fc3e3324f8 Mon Sep 17 00:00:00 2001 From: Daniele Date: Wed, 4 Dec 2013 11:52:46 +0100 Subject: [PATCH 1/9] Update localize.js Added scoped dictionaries. Localize.js will search in folder (scope) for resource file, very usefull in a modular system. Use this way: {{ 'myKey' | i18n:'myScope' }} You can have multiple scopes, without parameter, you will use the default resource file. --- src/localize.js | 373 +++++++++++++++++++++++++++--------------------- 1 file changed, 209 insertions(+), 164 deletions(-) diff --git a/src/localize.js b/src/localize.js index fbd492f..52848ef 100644 --- a/src/localize.js +++ b/src/localize.js @@ -9,180 +9,225 @@ */ angular.module('localization', []) - // localization service responsible for retrieving resource files from the server and - // managing the translation dictionary + // localization service responsible for retrieving resource files from the server and + // managing the translation dictionary .factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) { - var localize = { - // use the $window service to get the language of the user's browser - language:'', - // array to hold the localized resource string entries - dictionary:[], - // location of the resource file - url: undefined, - // flag to indicate if the service hs loaded the resource file - resourceFileLoaded:false, - - // success handler for all server communication - successCallback:function (data) { - // store the returned array in the dictionary - localize.dictionary = data; - // set the flag that the resource are loaded - localize.resourceFileLoaded = true; - // broadcast that the file has been loaded - $rootScope.$broadcast('localizeResourcesUpdated'); - }, - - // allows setting of language on the fly - setLanguage: function(value) { - localize.language = value; - localize.initLocalizedResources(); - }, - - // allows setting of resource url on the fly - setUrl: function(value) { - localize.url = value; - localize.initLocalizedResources(); - }, - - // builds the url for locating the resource file - buildUrl: function() { - if(!localize.language){ - var lang, androidLang; - // works for earlier version of Android (2.3.x) - if ($window.navigator && $window.navigator.userAgent && (androidLang = $window.navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { - lang = androidLang[1]; - } else { - // works for iOS, Android 4.x and other devices - lang = $window.navigator.userLanguage || $window.navigator.language; - } - // set language - localize.language = lang; - } - return 'i18n/resources-locale_' + localize.language + '.js'; - }, - - // loads the language resource file from the server - initLocalizedResources:function () { - // build the url to retrieve the localized resource file - var url = localize.url || localize.buildUrl(); - // request the resource file - $http({ method:"GET", url:url, cache:false }).success(localize.successCallback).error(function () { - // the request failed set the url to the default resource file - var url = '/i18n/resources-locale_default.js'; - // request the default resource file - $http({ method:"GET", url:url, cache:false }).success(localize.successCallback); + var localize = { + // use the $window service to get the language of the user's browser + language: '', + // array to hold the localized resource string entries + dictionary: [], + // array for scoped dictionaries + scopedDictionary: [], + // avoid multiple XHR issued due to files not loaded + scopeLoading: [], + // location of the resource file + url: undefined, + // flag to indicate if the service hs loaded the resource file + resourceFileLoaded: false, + + // success handler for all server communication + successCallback: function (data, scope) { + if (scope) { + localize.scopedDictionary[scope] = data; + localize.scopeLoading[scope] = false; + } else { + // store the returned array in the dictionary + localize.dictionary = data; + } + // set the flag that the resource are loaded + localize.resourceFileLoaded = true; + // broadcast that the file has been loaded + $rootScope.$broadcast('localizeResourcesUpdated'); + }, + + // allows setting of language on the fly + setLanguage: function (value) { + localize.language = value; + localize.initLocalizedResources(); + }, + + // allows setting of resource url on the fly + setUrl: function (value) { + localize.url = value; + localize.initLocalizedResources(); + }, + + // builds the url for locating the resource file + buildUrl: function (scope) { + if (!localize.language) { + var lang, androidLang; + // works for earlier version of Android (2.3.x) + if ($window.navigator && $window.navigator.userAgent && (androidLang = $window.navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { + lang = androidLang[1]; + } else { + // works for iOS, Android 4.x and other devices + lang = $window.navigator.userLanguage || $window.navigator.language; + } + // set language + localize.language = lang; + } + return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.js'; + }, + + // loads the language resource file from the server + initLocalizedResources: function (scope) { + // build the url to retrieve the localized resource file + var url = scope ? localize.buildUrl(scope) : localize.url || localize.buildUrl(); + // request the resource file + $http({ method: "GET", url: url, cache: false }) + .success(function(data) { + localize.successCallback(data, scope); + }) + .error(function () { + // the request failed set the url to the default resource file + var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.js'; + // request the default resource file + $http({ method: "GET", url: url, cache: false }) + .success(function(data) { + localize.successCallback(data, scope); + }) + .error(function() { + // avoid loop of hell in case scopedDic doesn't exists + localize.scopedDictionary[scope] = []; + localize.scopeLoading[scope] = false; }); - }, - - // checks the dictionary for a localized resource string - getLocalizedString: function(value) { - // default the result to an empty string - var result = ''; - - // make sure the dictionary has valid data - if ((localize.dictionary !== []) && (localize.dictionary.length > 0)) { - // use the filter service to only return those entries which match the value - // and only take the first result - var entry = $filter('filter')(localize.dictionary, function(element) { - return element.key === value; - } - )[0]; - - // set the result - result = entry.value; - } - // return the value to the call - return result; + }); + }, + + // returns scoped dic, if not present, issues a loading + getScopedDictionary: function(scope) { + var dic = localize.scopedDictionary[scope]; + if (!dic) { + if (!localize.scopeLoading[scope]) { + localize.scopeLoading[scope] = true; + localize.initLocalizedResources(scope); + } + dic = []; + } + return dic; + }, + + // checks the dictionary for a localized resource string + getLocalizedString: function (value, scope) { + // default the result to an empty string + var result = ''; + var dic; + // + if (!scope) { + dic = localize.dictionary; + } else { + dic = localize.getScopedDictionary(scope); + } + // if something is wrong, bad things will happens without this check.. + if (dic) { + // make sure the dictionary has valid data + if ((dic !== []) && (dic.length > 0)) { + // use the filter service to only return those entries which match the value + // and only take the first result + var entry = $filter('filter')(dic, function (element) { + return element.key === value; + } + )[0]; + + // set the result + result = entry.value; } - }; + } + // return the value to the call + return result; + } + }; - // force the load of the resource file - localize.initLocalizedResources(); + // force the load of the resource file + localize.initLocalizedResources(); - // return the local instance when called - return localize; + // return the local instance when called + return localize; } ]) - // simple translation filter - // usage {{ TOKEN | i18n }} + // simple translation filter + // usage {{ TOKEN | i18n }} + // usage {{ TOKEN | i18n:'scopeName' }} .filter('i18n', ['localize', function (localize) { - return function (input) { - return localize.getLocalizedString(input); - }; + return function (input, scope) { + return localize.getLocalizedString(input, scope); + }; }]) - // translation directive that can handle dynamic strings - // updates the text value of the attached element - // usage - // or - // - .directive('i18n', ['localize', function(localize){ - var i18nDirective = { - restrict:"EAC", - updateText:function(elm, token){ - var values = token.split('|'); - if (values.length >= 1) { - // construct the tag to insert into the element - var tag = localize.getLocalizedString(values[0]); - // update the element only if data was returned - if ((tag !== null) && (tag !== undefined) && (tag !== '')) { - if (values.length > 1) { - for (var index = 1; index < values.length; index++) { - var target = '{' + (index - 1) + '}'; - tag = tag.replace(target, values[index]); - } - } - // insert the text into the element - elm.text(tag); - }; + // translation directive that can handle dynamic strings + // updates the text value of the attached element + // usage + // or + // + .directive('i18n', ['localize', function (localize) { + var i18nDirective = { + restrict: "EAC", + updateText: function (elm, token) { + var values = token.split('|'); + if (values.length >= 1) { + // construct the tag to insert into the element + var tag = localize.getLocalizedString(values[0]); + // update the element only if data was returned + if ((tag !== null) && (tag !== undefined) && (tag !== '')) { + if (values.length > 1) { + for (var index = 1; index < values.length; index++) { + var target = '{' + (index - 1) + '}'; + tag = tag.replace(target, values[index]); } - }, - - link:function (scope, elm, attrs) { - scope.$on('localizeResourcesUpdated', function() { - i18nDirective.updateText(elm, attrs.i18n); - }); - - attrs.$observe('i18n', function (value) { - i18nDirective.updateText(elm, attrs.i18n); - }); + } + // insert the text into the element + elm.text(tag); } - }; - - return i18nDirective; + ; + } + }, + + link: function (scope, elm, attrs) { + scope.$on('localizeResourcesUpdated', function () { + i18nDirective.updateText(elm, attrs.i18n); + }); + + attrs.$observe('i18n', function (value) { + i18nDirective.updateText(elm, attrs.i18n); + }); + } + }; + + return i18nDirective; }]) - // translation directive that can handle dynamic strings - // updates the attribute value of the attached element - // usage - // or - // + // translation directive that can handle dynamic strings + // updates the attribute value of the attached element + // usage + // or + // .directive('i18nAttr', ['localize', function (localize) { - var i18NAttrDirective = { - restrict: "EAC", - updateText:function(elm, token){ - var values = token.split('|'); - // construct the tag to insert into the element - var tag = localize.getLocalizedString(values[0]); - // update the element only if data was returned - if ((tag !== null) && (tag !== undefined) && (tag !== '')) { - if (values.length > 2) { - for (var index = 2; index < values.length; index++) { - var target = '{' + (index - 2) + '}'; - tag = tag.replace(target, values[index]); - } - } - // insert the text into the element - elm.attr(values[1], tag); - } - }, - link: function (scope, elm, attrs) { - scope.$on('localizeResourcesUpdated', function() { - i18NAttrDirective.updateText(elm, attrs.i18nAttr); - }); - - attrs.$observe('i18nAttr', function (value) { - i18NAttrDirective.updateText(elm, value); - }); + var i18NAttrDirective = { + restrict: "EAC", + updateText: function (elm, token) { + var values = token.split('|'); + // construct the tag to insert into the element + var tag = localize.getLocalizedString(values[0]); + // update the element only if data was returned + if ((tag !== null) && (tag !== undefined) && (tag !== '')) { + if (values.length > 2) { + for (var index = 2; index < values.length; index++) { + var target = '{' + (index - 2) + '}'; + tag = tag.replace(target, values[index]); + } } - }; - - return i18NAttrDirective; - }]); \ No newline at end of file + // insert the text into the element + elm.attr(values[1], tag); + } + }, + link: function (scope, elm, attrs) { + scope.$on('localizeResourcesUpdated', function () { + i18NAttrDirective.updateText(elm, attrs.i18nAttr); + }); + + attrs.$observe('i18nAttr', function (value) { + i18NAttrDirective.updateText(elm, value); + }); + } + }; + + return i18NAttrDirective; + }]); From ba2493876ee24488c1b4ce17a827c9a3d7c50f5d Mon Sep 17 00:00:00 2001 From: Daniele Date: Wed, 4 Dec 2013 11:55:38 +0100 Subject: [PATCH 2/9] Update localize.js Fix indentation --- src/localize.js | 430 ++++++++++++++++++++++++------------------------ 1 file changed, 215 insertions(+), 215 deletions(-) diff --git a/src/localize.js b/src/localize.js index 52848ef..c0a465e 100644 --- a/src/localize.js +++ b/src/localize.js @@ -1,233 +1,233 @@ 'use strict'; - -/* - * An AngularJS Localization Service - * - * Written by Jim Lavin - * http://codingsmackdown.tv - * - */ - -angular.module('localization', []) - // localization service responsible for retrieving resource files from the server and - // managing the translation dictionary - .factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) { - var localize = { - // use the $window service to get the language of the user's browser - language: '', - // array to hold the localized resource string entries - dictionary: [], - // array for scoped dictionaries - scopedDictionary: [], - // avoid multiple XHR issued due to files not loaded - scopeLoading: [], - // location of the resource file - url: undefined, - // flag to indicate if the service hs loaded the resource file - resourceFileLoaded: false, - - // success handler for all server communication - successCallback: function (data, scope) { - if (scope) { - localize.scopedDictionary[scope] = data; - localize.scopeLoading[scope] = false; - } else { - // store the returned array in the dictionary - localize.dictionary = data; - } - // set the flag that the resource are loaded - localize.resourceFileLoaded = true; - // broadcast that the file has been loaded - $rootScope.$broadcast('localizeResourcesUpdated'); - }, - - // allows setting of language on the fly - setLanguage: function (value) { - localize.language = value; - localize.initLocalizedResources(); - }, - - // allows setting of resource url on the fly - setUrl: function (value) { - localize.url = value; - localize.initLocalizedResources(); - }, - - // builds the url for locating the resource file - buildUrl: function (scope) { - if (!localize.language) { - var lang, androidLang; - // works for earlier version of Android (2.3.x) - if ($window.navigator && $window.navigator.userAgent && (androidLang = $window.navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { - lang = androidLang[1]; + + /* + * An AngularJS Localization Service + * + * Written by Jim Lavin + * http://codingsmackdown.tv + * + */ + + angular.module('localization', []) + // localization service responsible for retrieving resource files from the server and + // managing the translation dictionary + .factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) { + var localize = { + // use the $window service to get the language of the user's browser + language: '', + // array to hold the localized resource string entries + dictionary: [], + // array for scoped dictionaries + scopedDictionary: [], + // avoid multiple XHR issued due to files not loaded + scopeLoading: [], + // location of the resource file + url: undefined, + // flag to indicate if the service hs loaded the resource file + resourceFileLoaded: false, + + // success handler for all server communication + successCallback: function (data, scope) { + if (scope) { + localize.scopedDictionary[scope] = data; + localize.scopeLoading[scope] = false; } else { - // works for iOS, Android 4.x and other devices - lang = $window.navigator.userLanguage || $window.navigator.language; + // store the returned array in the dictionary + localize.dictionary = data; } - // set language - localize.language = lang; - } - return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.js'; - }, - - // loads the language resource file from the server - initLocalizedResources: function (scope) { - // build the url to retrieve the localized resource file - var url = scope ? localize.buildUrl(scope) : localize.url || localize.buildUrl(); - // request the resource file - $http({ method: "GET", url: url, cache: false }) - .success(function(data) { - localize.successCallback(data, scope); - }) - .error(function () { - // the request failed set the url to the default resource file - var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.js'; - // request the default resource file - $http({ method: "GET", url: url, cache: false }) - .success(function(data) { - localize.successCallback(data, scope); - }) - .error(function() { - // avoid loop of hell in case scopedDic doesn't exists - localize.scopedDictionary[scope] = []; - localize.scopeLoading[scope] = false; - }); - }); - }, - - // returns scoped dic, if not present, issues a loading - getScopedDictionary: function(scope) { - var dic = localize.scopedDictionary[scope]; - if (!dic) { - if (!localize.scopeLoading[scope]) { - localize.scopeLoading[scope] = true; - localize.initLocalizedResources(scope); + // set the flag that the resource are loaded + localize.resourceFileLoaded = true; + // broadcast that the file has been loaded + $rootScope.$broadcast('localizeResourcesUpdated'); + }, + + // allows setting of language on the fly + setLanguage: function (value) { + localize.language = value; + localize.initLocalizedResources(); + }, + + // allows setting of resource url on the fly + setUrl: function (value) { + localize.url = value; + localize.initLocalizedResources(); + }, + + // builds the url for locating the resource file + buildUrl: function (scope) { + if (!localize.language) { + var lang, androidLang; + // works for earlier version of Android (2.3.x) + if ($window.navigator && $window.navigator.userAgent && (androidLang = $window.navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { + lang = androidLang[1]; + } else { + // works for iOS, Android 4.x and other devices + lang = $window.navigator.userLanguage || $window.navigator.language; + } + // set language + localize.language = lang; } - dic = []; - } - return dic; - }, - - // checks the dictionary for a localized resource string - getLocalizedString: function (value, scope) { - // default the result to an empty string - var result = ''; - var dic; - // - if (!scope) { - dic = localize.dictionary; - } else { - dic = localize.getScopedDictionary(scope); + return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.js'; + }, + + // loads the language resource file from the server + initLocalizedResources: function (scope) { + // build the url to retrieve the localized resource file + var url = scope ? localize.buildUrl(scope) : localize.url || localize.buildUrl(); + // request the resource file + $http({ method: "GET", url: url, cache: false }) + .success(function(data) { + localize.successCallback(data, scope); + }) + .error(function () { + // the request failed set the url to the default resource file + var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.js'; + // request the default resource file + $http({ method: "GET", url: url, cache: false }) + .success(function(data) { + localize.successCallback(data, scope); + }) + .error(function() { + // avoid loop of hell in case scopedDic doesn't exists + localize.scopedDictionary[scope] = []; + localize.scopeLoading[scope] = false; + }); + }); + }, + + // returns scoped dic, if not present, issues a loading + getScopedDictionary: function(scope) { + var dic = localize.scopedDictionary[scope]; + if (!dic) { + if (!localize.scopeLoading[scope]) { + localize.scopeLoading[scope] = true; + localize.initLocalizedResources(scope); + } + dic = []; + } + return dic; + }, + + // checks the dictionary for a localized resource string + getLocalizedString: function (value, scope) { + // default the result to an empty string + var result = ''; + var dic; + // + if (!scope) { + dic = localize.dictionary; + } else { + dic = localize.getScopedDictionary(scope); + } + // if something is wrong, bad things will happens without this check.. + if (dic) { + // make sure the dictionary has valid data + if ((dic !== []) && (dic.length > 0)) { + // use the filter service to only return those entries which match the value + // and only take the first result + var entry = $filter('filter')(dic, function (element) { + return element.key === value; + } + )[0]; + + // set the result + result = entry.value; + } + } + // return the value to the call + return result; } - // if something is wrong, bad things will happens without this check.. - if (dic) { - // make sure the dictionary has valid data - if ((dic !== []) && (dic.length > 0)) { - // use the filter service to only return those entries which match the value - // and only take the first result - var entry = $filter('filter')(dic, function (element) { - return element.key === value; + }; + + // force the load of the resource file + localize.initLocalizedResources(); + + // return the local instance when called + return localize; + } ]) + // simple translation filter + // usage {{ TOKEN | i18n }} + // usage {{ TOKEN | i18n:'scopeName' }} + .filter('i18n', ['localize', function (localize) { + return function (input, scope) { + return localize.getLocalizedString(input, scope); + }; + }]) + // translation directive that can handle dynamic strings + // updates the text value of the attached element + // usage + // or + // + .directive('i18n', ['localize', function (localize) { + var i18nDirective = { + restrict: "EAC", + updateText: function (elm, token) { + var values = token.split('|'); + if (values.length >= 1) { + // construct the tag to insert into the element + var tag = localize.getLocalizedString(values[0]); + // update the element only if data was returned + if ((tag !== null) && (tag !== undefined) && (tag !== '')) { + if (values.length > 1) { + for (var index = 1; index < values.length; index++) { + var target = '{' + (index - 1) + '}'; + tag = tag.replace(target, values[index]); } - )[0]; - - // set the result - result = entry.value; + } + // insert the text into the element + elm.text(tag); + } + ; } + }, + + link: function (scope, elm, attrs) { + scope.$on('localizeResourcesUpdated', function () { + i18nDirective.updateText(elm, attrs.i18n); + }); + + attrs.$observe('i18n', function (value) { + i18nDirective.updateText(elm, attrs.i18n); + }); } - // return the value to the call - return result; - } - }; - - // force the load of the resource file - localize.initLocalizedResources(); - - // return the local instance when called - return localize; - } ]) - // simple translation filter - // usage {{ TOKEN | i18n }} - // usage {{ TOKEN | i18n:'scopeName' }} - .filter('i18n', ['localize', function (localize) { - return function (input, scope) { - return localize.getLocalizedString(input, scope); - }; - }]) - // translation directive that can handle dynamic strings - // updates the text value of the attached element - // usage - // or - // - .directive('i18n', ['localize', function (localize) { - var i18nDirective = { - restrict: "EAC", - updateText: function (elm, token) { - var values = token.split('|'); - if (values.length >= 1) { + }; + + return i18nDirective; + }]) + // translation directive that can handle dynamic strings + // updates the attribute value of the attached element + // usage + // or + // + .directive('i18nAttr', ['localize', function (localize) { + var i18NAttrDirective = { + restrict: "EAC", + updateText: function (elm, token) { + var values = token.split('|'); // construct the tag to insert into the element var tag = localize.getLocalizedString(values[0]); // update the element only if data was returned if ((tag !== null) && (tag !== undefined) && (tag !== '')) { - if (values.length > 1) { - for (var index = 1; index < values.length; index++) { - var target = '{' + (index - 1) + '}'; + if (values.length > 2) { + for (var index = 2; index < values.length; index++) { + var target = '{' + (index - 2) + '}'; tag = tag.replace(target, values[index]); } } // insert the text into the element - elm.text(tag); + elm.attr(values[1], tag); } - ; - } - }, - - link: function (scope, elm, attrs) { - scope.$on('localizeResourcesUpdated', function () { - i18nDirective.updateText(elm, attrs.i18n); - }); - - attrs.$observe('i18n', function (value) { - i18nDirective.updateText(elm, attrs.i18n); - }); - } - }; - - return i18nDirective; - }]) - // translation directive that can handle dynamic strings - // updates the attribute value of the attached element - // usage - // or - // - .directive('i18nAttr', ['localize', function (localize) { - var i18NAttrDirective = { - restrict: "EAC", - updateText: function (elm, token) { - var values = token.split('|'); - // construct the tag to insert into the element - var tag = localize.getLocalizedString(values[0]); - // update the element only if data was returned - if ((tag !== null) && (tag !== undefined) && (tag !== '')) { - if (values.length > 2) { - for (var index = 2; index < values.length; index++) { - var target = '{' + (index - 2) + '}'; - tag = tag.replace(target, values[index]); - } - } - // insert the text into the element - elm.attr(values[1], tag); + }, + link: function (scope, elm, attrs) { + scope.$on('localizeResourcesUpdated', function () { + i18NAttrDirective.updateText(elm, attrs.i18nAttr); + }); + + attrs.$observe('i18nAttr', function (value) { + i18NAttrDirective.updateText(elm, value); + }); } - }, - link: function (scope, elm, attrs) { - scope.$on('localizeResourcesUpdated', function () { - i18NAttrDirective.updateText(elm, attrs.i18nAttr); - }); - - attrs.$observe('i18nAttr', function (value) { - i18NAttrDirective.updateText(elm, value); - }); - } - }; - - return i18NAttrDirective; - }]); + }; + + return i18NAttrDirective; + }]); From 7275d38d5207eeb59fb228771b346b6fa089468c Mon Sep 17 00:00:00 2001 From: Daniele Brugnara Date: Wed, 4 Dec 2013 12:03:03 +0100 Subject: [PATCH 3/9] fix indentation --- src/localize.js | 392 ++++++++++++++++++++++++------------------------ 1 file changed, 196 insertions(+), 196 deletions(-) diff --git a/src/localize.js b/src/localize.js index c0a465e..40e18fb 100644 --- a/src/localize.js +++ b/src/localize.js @@ -1,233 +1,233 @@ 'use strict'; - - /* - * An AngularJS Localization Service - * - * Written by Jim Lavin - * http://codingsmackdown.tv - * - */ - - angular.module('localization', []) + +/* + * An AngularJS Localization Service + * + * Written by Jim Lavin + * http://codingsmackdown.tv + * + */ + +angular.module('localization', []) // localization service responsible for retrieving resource files from the server and // managing the translation dictionary - .factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) { + .factory('localize', ['$http', '$rootScope', '$window', '$filter', function ($http, $rootScope, $window, $filter) { var localize = { - // use the $window service to get the language of the user's browser - language: '', - // array to hold the localized resource string entries - dictionary: [], - // array for scoped dictionaries - scopedDictionary: [], - // avoid multiple XHR issued due to files not loaded - scopeLoading: [], - // location of the resource file - url: undefined, - // flag to indicate if the service hs loaded the resource file - resourceFileLoaded: false, - - // success handler for all server communication - successCallback: function (data, scope) { - if (scope) { - localize.scopedDictionary[scope] = data; - localize.scopeLoading[scope] = false; - } else { - // store the returned array in the dictionary - localize.dictionary = data; - } - // set the flag that the resource are loaded - localize.resourceFileLoaded = true; - // broadcast that the file has been loaded - $rootScope.$broadcast('localizeResourcesUpdated'); - }, - - // allows setting of language on the fly - setLanguage: function (value) { - localize.language = value; - localize.initLocalizedResources(); - }, - - // allows setting of resource url on the fly - setUrl: function (value) { - localize.url = value; - localize.initLocalizedResources(); - }, - - // builds the url for locating the resource file - buildUrl: function (scope) { - if (!localize.language) { - var lang, androidLang; - // works for earlier version of Android (2.3.x) - if ($window.navigator && $window.navigator.userAgent && (androidLang = $window.navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { - lang = androidLang[1]; - } else { - // works for iOS, Android 4.x and other devices - lang = $window.navigator.userLanguage || $window.navigator.language; - } - // set language - localize.language = lang; - } - return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.js'; - }, - - // loads the language resource file from the server - initLocalizedResources: function (scope) { - // build the url to retrieve the localized resource file - var url = scope ? localize.buildUrl(scope) : localize.url || localize.buildUrl(); - // request the resource file - $http({ method: "GET", url: url, cache: false }) - .success(function(data) { - localize.successCallback(data, scope); - }) - .error(function () { - // the request failed set the url to the default resource file - var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.js'; - // request the default resource file - $http({ method: "GET", url: url, cache: false }) - .success(function(data) { - localize.successCallback(data, scope); - }) - .error(function() { - // avoid loop of hell in case scopedDic doesn't exists - localize.scopedDictionary[scope] = []; + // use the $window service to get the language of the user's browser + language: '', + // array to hold the localized resource string entries + dictionary: [], + // array for scoped dictionaries + scopedDictionary: [], + // avoid multiple XHR issued due to files not loaded + scopeLoading: [], + // location of the resource file + url: undefined, + // flag to indicate if the service hs loaded the resource file + resourceFileLoaded: false, + + // success handler for all server communication + successCallback: function (data, scope) { + if (scope) { + localize.scopedDictionary[scope] = data; localize.scopeLoading[scope] = false; - }); - }); - }, - - // returns scoped dic, if not present, issues a loading - getScopedDictionary: function(scope) { - var dic = localize.scopedDictionary[scope]; - if (!dic) { - if (!localize.scopeLoading[scope]) { - localize.scopeLoading[scope] = true; - localize.initLocalizedResources(scope); - } - dic = []; - } - return dic; - }, - - // checks the dictionary for a localized resource string - getLocalizedString: function (value, scope) { - // default the result to an empty string - var result = ''; - var dic; - // - if (!scope) { - dic = localize.dictionary; - } else { - dic = localize.getScopedDictionary(scope); - } - // if something is wrong, bad things will happens without this check.. - if (dic) { - // make sure the dictionary has valid data - if ((dic !== []) && (dic.length > 0)) { - // use the filter service to only return those entries which match the value - // and only take the first result - var entry = $filter('filter')(dic, function (element) { - return element.key === value; + } else { + // store the returned array in the dictionary + localize.dictionary = data; + } + // set the flag that the resource are loaded + localize.resourceFileLoaded = true; + // broadcast that the file has been loaded + $rootScope.$broadcast('localizeResourcesUpdated'); + }, + + // allows setting of language on the fly + setLanguage: function (value) { + localize.language = value; + localize.initLocalizedResources(); + }, + + // allows setting of resource url on the fly + setUrl: function (value) { + localize.url = value; + localize.initLocalizedResources(); + }, + + // builds the url for locating the resource file + buildUrl: function (scope) { + if (!localize.language) { + var lang, androidLang; + // works for earlier version of Android (2.3.x) + if ($window.navigator && $window.navigator.userAgent && (androidLang = $window.navigator.userAgent.match(/android.*\W(\w\w)-(\w\w)\W/i))) { + lang = androidLang[1]; + } else { + // works for iOS, Android 4.x and other devices + lang = $window.navigator.userLanguage || $window.navigator.language; } - )[0]; - - // set the result - result = entry.value; - } + // set language + localize.language = lang; + } + return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.js'; + }, + + // loads the language resource file from the server + initLocalizedResources: function (scope) { + // build the url to retrieve the localized resource file + var url = scope ? localize.buildUrl(scope) : localize.url || localize.buildUrl(); + // request the resource file + $http({ method: "GET", url: url, cache: false }) + .success(function(data) { + localize.successCallback(data, scope); + }) + .error(function () { + // the request failed set the url to the default resource file + var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.js'; + // request the default resource file + $http({ method: "GET", url: url, cache: false }) + .success(function(data) { + localize.successCallback(data, scope); + }) + .error(function() { + // avoid loop of hell in case scopedDic doesn't exists + localize.scopedDictionary[scope] = []; + localize.scopeLoading[scope] = false; + }); + }); + }, + + // returns scoped dic, if not present, issues a loading + getScopedDictionary: function(scope) { + var dic = localize.scopedDictionary[scope]; + if (!dic) { + if (!localize.scopeLoading[scope]) { + localize.scopeLoading[scope] = true; + localize.initLocalizedResources(scope); + } + dic = []; + } + return dic; + }, + + // checks the dictionary for a localized resource string + getLocalizedString: function (value, scope) { + // default the result to an empty string + var result = ''; + var dic; + // + if (!scope) { + dic = localize.dictionary; + } else { + dic = localize.getScopedDictionary(scope); + } + // if something is wrong, bad things will happens without this check.. + if (dic) { + // make sure the dictionary has valid data + if ((dic !== []) && (dic.length > 0)) { + // use the filter service to only return those entries which match the value + // and only take the first result + var entry = $filter('filter')(dic, function (element) { + return element.key === value; + } + )[0]; + + // set the result + result = entry.value; + } + } + // return the value to the call + return result; } - // return the value to the call - return result; - } }; - + // force the load of the resource file localize.initLocalizedResources(); - + // return the local instance when called return localize; - } ]) + } ]) // simple translation filter // usage {{ TOKEN | i18n }} // usage {{ TOKEN | i18n:'scopeName' }} - .filter('i18n', ['localize', function (localize) { + .filter('i18n', ['localize', function (localize) { return function (input, scope) { - return localize.getLocalizedString(input, scope); + return localize.getLocalizedString(input, scope); }; - }]) + }]) // translation directive that can handle dynamic strings // updates the text value of the attached element // usage // or // - .directive('i18n', ['localize', function (localize) { + .directive('i18n', ['localize', function (localize) { var i18nDirective = { - restrict: "EAC", - updateText: function (elm, token) { - var values = token.split('|'); - if (values.length >= 1) { - // construct the tag to insert into the element - var tag = localize.getLocalizedString(values[0]); - // update the element only if data was returned - if ((tag !== null) && (tag !== undefined) && (tag !== '')) { - if (values.length > 1) { - for (var index = 1; index < values.length; index++) { - var target = '{' + (index - 1) + '}'; - tag = tag.replace(target, values[index]); - } + restrict: "EAC", + updateText: function (elm, token) { + var values = token.split('|'); + if (values.length >= 1) { + // construct the tag to insert into the element + var tag = localize.getLocalizedString(values[0]); + // update the element only if data was returned + if ((tag !== null) && (tag !== undefined) && (tag !== '')) { + if (values.length > 1) { + for (var index = 1; index < values.length; index++) { + var target = '{' + (index - 1) + '}'; + tag = tag.replace(target, values[index]); + } + } + // insert the text into the element + elm.text(tag); + } + ; } - // insert the text into the element - elm.text(tag); - } - ; + }, + + link: function (scope, elm, attrs) { + scope.$on('localizeResourcesUpdated', function () { + i18nDirective.updateText(elm, attrs.i18n); + }); + + attrs.$observe('i18n', function (value) { + i18nDirective.updateText(elm, attrs.i18n); + }); } - }, - - link: function (scope, elm, attrs) { - scope.$on('localizeResourcesUpdated', function () { - i18nDirective.updateText(elm, attrs.i18n); - }); - - attrs.$observe('i18n', function (value) { - i18nDirective.updateText(elm, attrs.i18n); - }); - } }; - + return i18nDirective; - }]) + }]) // translation directive that can handle dynamic strings // updates the attribute value of the attached element // usage // or // - .directive('i18nAttr', ['localize', function (localize) { + .directive('i18nAttr', ['localize', function (localize) { var i18NAttrDirective = { - restrict: "EAC", - updateText: function (elm, token) { - var values = token.split('|'); - // construct the tag to insert into the element - var tag = localize.getLocalizedString(values[0]); - // update the element only if data was returned - if ((tag !== null) && (tag !== undefined) && (tag !== '')) { - if (values.length > 2) { - for (var index = 2; index < values.length; index++) { - var target = '{' + (index - 2) + '}'; - tag = tag.replace(target, values[index]); + restrict: "EAC", + updateText: function (elm, token) { + var values = token.split('|'); + // construct the tag to insert into the element + var tag = localize.getLocalizedString(values[0]); + // update the element only if data was returned + if ((tag !== null) && (tag !== undefined) && (tag !== '')) { + if (values.length > 2) { + for (var index = 2; index < values.length; index++) { + var target = '{' + (index - 2) + '}'; + tag = tag.replace(target, values[index]); + } + } + // insert the text into the element + elm.attr(values[1], tag); } - } - // insert the text into the element - elm.attr(values[1], tag); + }, + link: function (scope, elm, attrs) { + scope.$on('localizeResourcesUpdated', function () { + i18NAttrDirective.updateText(elm, attrs.i18nAttr); + }); + + attrs.$observe('i18nAttr', function (value) { + i18NAttrDirective.updateText(elm, value); + }); } - }, - link: function (scope, elm, attrs) { - scope.$on('localizeResourcesUpdated', function () { - i18NAttrDirective.updateText(elm, attrs.i18nAttr); - }); - - attrs.$observe('i18nAttr', function (value) { - i18NAttrDirective.updateText(elm, value); - }); - } }; - + return i18NAttrDirective; - }]); + }]); From 4687a205c2c034365a85600edf67bb7a273b1cc2 Mon Sep 17 00:00:00 2001 From: Daniele Date: Wed, 4 Dec 2013 12:39:57 +0100 Subject: [PATCH 4/9] Update README.md Added scoped dictionaries example and explanation. --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 832c0b2..c60df36 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,19 @@ The service returns a localized string based on the current locale of the browse You can inject the service into a controller or use it via the i18n filter or the i18n directive provided in the code. +## Scoped Dictionaries + +This feature allow you to use a dictionary for each one of your components. A simple example will follow: + + |_ app + |_ i18n + |_ resources-locale_defaults.js + |_ component-1 + |_ resources-locale_defaults.js + + {{ "clickme" | i18n }} => Click me + {{ "clickme" | i18n:'component-1' }} => Click me, I dare you! + ## Wiring It Up You need to follow a few steps to wire the service into your app: From 035b59dc95c628bd65930ec7c56a76ea562f5f58 Mon Sep 17 00:00:00 2001 From: Daniele Brugnara Date: Wed, 4 Dec 2013 12:47:16 +0100 Subject: [PATCH 5/9] typo error --- src/localize.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/localize.js b/src/localize.js index 40e18fb..fb80224 100644 --- a/src/localize.js +++ b/src/localize.js @@ -35,7 +35,7 @@ angular.module('localization', []) // store the returned array in the dictionary localize.dictionary = data; } - // set the flag that the resource are loaded + // set that the resource are loaded localize.resourceFileLoaded = true; // broadcast that the file has been loaded $rootScope.$broadcast('localizeResourcesUpdated'); From 9c3b7c98f866d107be6b1cde35a3dff074f56155 Mon Sep 17 00:00:00 2001 From: Daniele Date: Wed, 4 Dec 2013 12:55:22 +0100 Subject: [PATCH 6/9] Update README.md Moved a section of README in the right context. --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index c60df36..4dc4f27 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,6 @@ The service returns a localized string based on the current locale of the browse You can inject the service into a controller or use it via the i18n filter or the i18n directive provided in the code. -## Scoped Dictionaries - -This feature allow you to use a dictionary for each one of your components. A simple example will follow: - - |_ app - |_ i18n - |_ resources-locale_defaults.js - |_ component-1 - |_ resources-locale_defaults.js - - {{ "clickme" | i18n }} => Click me - {{ "clickme" | i18n:'component-1' }} => Click me, I dare you! - ## Wiring It Up You need to follow a few steps to wire the service into your app: @@ -49,6 +36,19 @@ I've created a sample app that uses the Resource Localization Service to provide There is a delay loading the resource file, you may need to use the filter instead of the directive on the home page. This is due to the fact that the directive is only called once per instance where a filter is re-evaluated each time the DOM is compiled. +## Scoped Dictionaries + +This feature allow you to use a dictionary for each one of your components. A simple example will follow: + + |_ app + |_ i18n + |_ resources-locale_defaults.js + |_ component-1 + |_ resources-locale_defaults.js + + {{ "clickme" | i18n }} => Click me + {{ "clickme" | i18n:'component-1' }} => Click me, I dare you! + ## Change Log ### 0.1.2 - 09/26/2013 From 6a4842c69d388a346f519324be6bbf28b6dd35c8 Mon Sep 17 00:00:00 2001 From: Daniele Brugnara Date: Fri, 20 Dec 2013 14:42:49 +0100 Subject: [PATCH 7/9] =?UTF-8?q?Modificato=20da=20js=20a=20json=20per=20com?= =?UTF-8?q?patibilit=C3=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/localize.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/localize.js b/src/localize.js index fb80224..59a92e5 100644 --- a/src/localize.js +++ b/src/localize.js @@ -67,7 +67,7 @@ angular.module('localization', []) // set language localize.language = lang; } - return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.js'; + return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.json'; }, // loads the language resource file from the server @@ -81,7 +81,7 @@ angular.module('localization', []) }) .error(function () { // the request failed set the url to the default resource file - var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.js'; + var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.json'; // request the default resource file $http({ method: "GET", url: url, cache: false }) .success(function(data) { @@ -230,4 +230,4 @@ angular.module('localization', []) }; return i18NAttrDirective; - }]); + }]); \ No newline at end of file From 30b32ae1cc0c992ad446b19336ae75af92ece9b7 Mon Sep 17 00:00:00 2001 From: Daniele Brugnara Date: Fri, 20 Dec 2013 15:22:02 +0100 Subject: [PATCH 8/9] renamed from js to json --- ...{resources-locale_default.js => resources-locale_default.json} | 0 .../{resources-locale_en-US.js => resources-locale_en-US.json} | 0 .../{resources-locale_es-es.js => resources-locale_es-es.json} | 0 app/i18n/{resources-locale_es.js => resources-locale_es.json} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename app/i18n/{resources-locale_default.js => resources-locale_default.json} (100%) rename app/i18n/{resources-locale_en-US.js => resources-locale_en-US.json} (100%) rename app/i18n/{resources-locale_es-es.js => resources-locale_es-es.json} (100%) rename app/i18n/{resources-locale_es.js => resources-locale_es.json} (100%) diff --git a/app/i18n/resources-locale_default.js b/app/i18n/resources-locale_default.json similarity index 100% rename from app/i18n/resources-locale_default.js rename to app/i18n/resources-locale_default.json diff --git a/app/i18n/resources-locale_en-US.js b/app/i18n/resources-locale_en-US.json similarity index 100% rename from app/i18n/resources-locale_en-US.js rename to app/i18n/resources-locale_en-US.json diff --git a/app/i18n/resources-locale_es-es.js b/app/i18n/resources-locale_es-es.json similarity index 100% rename from app/i18n/resources-locale_es-es.js rename to app/i18n/resources-locale_es-es.json diff --git a/app/i18n/resources-locale_es.js b/app/i18n/resources-locale_es.json similarity index 100% rename from app/i18n/resources-locale_es.js rename to app/i18n/resources-locale_es.json From b943a286018195d3e2556d212658713df0bc7d58 Mon Sep 17 00:00:00 2001 From: Francesco Spina Date: Thu, 9 Jan 2014 15:23:19 +0100 Subject: [PATCH 9/9] Modificato path per caricare i resource dai singoli moduli --- src/localize.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/localize.js b/src/localize.js index 59a92e5..2fb1a8d 100644 --- a/src/localize.js +++ b/src/localize.js @@ -67,7 +67,8 @@ angular.module('localization', []) // set language localize.language = lang; } - return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.json'; + //return 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_' + localize.language + '.json'; + return (scope ? 'modules/' + scope + '/i18n' : 'i18n') + '/resources-locale_' + localize.language + '.json'; }, // loads the language resource file from the server @@ -81,7 +82,8 @@ angular.module('localization', []) }) .error(function () { // the request failed set the url to the default resource file - var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.json'; + //var url = 'i18n/' + (scope ? scope + '/' : '') + 'resources-locale_default.json'; + var url = (scope ? 'modules/' + scope + '/i18n' : 'i18n') + '/resources-locale_default.json'; // request the default resource file $http({ method: "GET", url: url, cache: false }) .success(function(data) {