diff --git a/dist/angular-gettext.js b/dist/angular-gettext.js index 5583459..9ee8e51 100644 --- a/dist/angular-gettext.js +++ b/dist/angular-gettext.js @@ -41,6 +41,10 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", $rootScope.$broadcast('gettextLanguageChanged'); } + function getInternalNamespaceName(namepsace) { + return namepsace ? ('$$_ns_' + namepsace) : namepsace; + } + catalog = { debug: false, debugPrefix: '[MISSING]: ', @@ -61,11 +65,17 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", return this.currentLanguage; }, - setStrings: function (language, strings) { + setStrings: function (language, strings, namepsace) { if (!this.strings[language]) { this.strings[language] = {}; } + namepsace = getInternalNamespaceName(namepsace); + + if (namepsace && !this.strings[language][namepsace]) { + this.strings[language][namepsace] = {}; + } + for (var key in strings) { var val = strings[key]; @@ -86,28 +96,37 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", var str = val[context]; val[context] = angular.isArray(str) ? str : [str]; } - this.strings[language][key] = val; + + if (namepsace) { + this.strings[language][namepsace][key] = val; + } else { + this.strings[language][key] = val; + } } broadcastUpdated(); }, - getStringForm: function (string, n, context) { + getStringForm: function (string, n, context, namepsace) { var stringTable = this.strings[this.currentLanguage] || {}; + namepsace = getInternalNamespaceName(namepsace); + if (namepsace) { + stringTable = stringTable[namepsace] || {}; + } var contexts = stringTable[string] || {}; var plurals = contexts[context || noContext] || []; return plurals[n]; }, - getString: function (string, scope, context) { - string = this.getStringForm(string, 0, context) || prefixDebug(string); + getString: function (string, scope, context, namepsace) { + string = this.getStringForm(string, 0, context, namepsace) || prefixDebug(string); string = scope ? $interpolate(string)(scope) : string; return addTranslatedMarkers(string); }, - getPlural: function (n, string, stringPlural, scope, context) { + getPlural: function (n, string, stringPlural, scope, context, namepsace) { var form = gettextPlurals(this.currentLanguage, n); - string = this.getStringForm(string, form, context) || prefixDebug(n === 1 ? string : stringPlural); + string = this.getStringForm(string, form, context, namepsace) || prefixDebug(n === 1 ? string : stringPlural); if (scope) { scope.$count = n; string = $interpolate(string)(scope); @@ -115,7 +134,7 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", return addTranslatedMarkers(string); }, - loadRemote: function (url) { + loadRemote: function (url, namepsace) { return $http({ method: 'GET', url: url, @@ -123,7 +142,7 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", }).then(function (response) { var data = response.data; for (var lang in data) { - catalog.setStrings(lang, data[lang]); + catalog.setStrings(lang, data[lang], namepsace); } return response; }); @@ -166,6 +185,7 @@ angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$ var msgid = trim(element.html()); var translatePlural = attrs.translatePlural; var translateContext = attrs.translateContext; + var namespace = attrs.translate; if (msie <= 8) { // Workaround fix relating to angular adding a comment node to @@ -187,9 +207,9 @@ angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$ if (translatePlural) { scope = pluralScope || (pluralScope = scope.$new()); scope.$count = countFn(scope); - translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural, null, translateContext); + translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural, null, translateContext, namespace); } else { - translated = gettextCatalog.getString(msgid, null, translateContext); + translated = gettextCatalog.getString(msgid, null, translateContext, namespace); } var oldContents = element.contents(); @@ -231,8 +251,8 @@ angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$ }]); angular.module('gettext').filter('translate', ["gettextCatalog", function (gettextCatalog) { - function filter(input, context) { - return gettextCatalog.getString(input, null, context); + function filter(input, context, namespace) { + return gettextCatalog.getString(input, null, context, namespace); } filter.$stateful = true; return filter; diff --git a/dist/angular-gettext.min.js b/dist/angular-gettext.min.js index 3823944..1a23471 100644 --- a/dist/angular-gettext.min.js +++ b/dist/angular-gettext.min.js @@ -1 +1 @@ -angular.module("gettext",[]),angular.module("gettext").constant("gettext",function(a){return a}),angular.module("gettext").factory("gettextCatalog",["gettextPlurals","$http","$cacheFactory","$interpolate","$rootScope",function(a,b,c,d,e){function f(){e.$broadcast("gettextLanguageChanged")}var g,h="$$noContext",i='test',j=angular.element(""+i+"").html()!==i,k=function(a){return g.debug&&g.currentLanguage!==g.baseLanguage?g.debugPrefix+a:a},l=function(a){return g.showTranslatedMarkers?g.translatedMarkerPrefix+a+g.translatedMarkerSuffix:a};return g={debug:!1,debugPrefix:"[MISSING]: ",showTranslatedMarkers:!1,translatedMarkerPrefix:"[",translatedMarkerSuffix:"]",strings:{},baseLanguage:"en",currentLanguage:"en",cache:c("strings"),setCurrentLanguage:function(a){this.currentLanguage=a,f()},getCurrentLanguage:function(){return this.currentLanguage},setStrings:function(a,b){this.strings[a]||(this.strings[a]={});for(var c in b){var d=b[c];if(j&&(c=angular.element(""+c+"").html()),angular.isString(d)||angular.isArray(d)){var e={};e[h]=d,d=e}for(var g in d){var i=d[g];d[g]=angular.isArray(i)?i:[i]}this.strings[a][c]=d}f()},getStringForm:function(a,b,c){var d=this.strings[this.currentLanguage]||{},e=d[a]||{},f=e[c||h]||[];return f[b]},getString:function(a,b,c){return a=this.getStringForm(a,0,c)||k(a),a=b?d(a)(b):a,l(a)},getPlural:function(b,c,e,f,g){var h=a(this.currentLanguage,b);return c=this.getStringForm(c,h,g)||k(1===b?c:e),f&&(f.$count=b,c=d(c)(f)),l(c)},loadRemote:function(a){return b({method:"GET",url:a,cache:g.cache}).then(function(a){var b=a.data;for(var c in b)g.setStrings(c,b[c]);return a})}}}]),angular.module("gettext").directive("translate",["gettextCatalog","$parse","$animate","$compile","$window",function(a,b,c,d,e){function f(a,b,c){if(!a)throw new Error("You should add a "+b+" attribute whenever you add a "+c+" attribute.")}var g=function(){return String.prototype.trim?function(a){return"string"==typeof a?a.trim():a}:function(a){return"string"==typeof a?a.replace(/^\s*/,"").replace(/\s*$/,""):a}}(),h=parseInt((/msie (\d+)/.exec(angular.lowercase(e.navigator.userAgent))||[])[1],10);return{restrict:"AE",terminal:!0,compile:function(e,i){f(!i.translatePlural||i.translateN,"translate-n","translate-plural"),f(!i.translateN||i.translatePlural,"translate-plural","translate-n");var j=g(e.html()),k=i.translatePlural,l=i.translateContext;return 8>=h&&""===j.slice(-13)&&(j=j.slice(0,-13)),{post:function(e,f,h){function i(){var b;k?(e=n||(n=e.$new()),e.$count=m(e),b=a.getPlural(e.$count,j,k,null,l)):b=a.getString(j,null,l);var h=f.contents();if(0!==h.length){if(b===g(h.html()))return void(o&&d(h)(e));var i=angular.element(""+b+"");d(i.contents())(e);var p=i.contents();c.enter(p,f),c.leave(h)}}var m=b(h.translateN),n=null,o=!0;h.translateN&&e.$watch(h.translateN,i),e.$on("gettextLanguageChanged",i),i(),o=!1}}}}}]),angular.module("gettext").filter("translate",["gettextCatalog",function(a){function b(b,c){return a.getString(b,null,c)}return b.$stateful=!0,b}]),angular.module("gettext").factory("gettextPlurals",function(){return function(a,b){switch(a){case"ay":case"bo":case"cgg":case"dz":case"fa":case"id":case"ja":case"jbo":case"ka":case"kk":case"km":case"ko":case"ky":case"lo":case"ms":case"my":case"sah":case"su":case"th":case"tt":case"ug":case"vi":case"wo":case"zh":return 0;case"is":return b%10!=1||b%100==11?1:0;case"jv":return 0!=b?1:0;case"mk":return 1==b||b%10==1?0:1;case"ach":case"ak":case"am":case"arn":case"br":case"fil":case"fr":case"gun":case"ln":case"mfe":case"mg":case"mi":case"oc":case"pt_BR":case"tg":case"ti":case"tr":case"uz":case"wa":case"zh":return b>1?1:0;case"lv":return b%10==1&&b%100!=11?0:0!=b?1:2;case"lt":return b%10==1&&b%100!=11?0:b%10>=2&&(10>b%100||b%100>=20)?1:2;case"be":case"bs":case"hr":case"ru":case"sr":case"uk":return b%10==1&&b%100!=11?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"mnk":return 0==b?0:1==b?1:2;case"ro":return 1==b?0:0==b||b%100>0&&20>b%100?1:2;case"pl":return 1==b?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"cs":case"sk":return 1==b?0:b>=2&&4>=b?1:2;case"sl":return b%100==1?1:b%100==2?2:b%100==3||b%100==4?3:0;case"mt":return 1==b?0:0==b||b%100>1&&11>b%100?1:b%100>10&&20>b%100?2:3;case"gd":return 1==b||11==b?0:2==b||12==b?1:b>2&&20>b?2:3;case"cy":return 1==b?0:2==b?1:8!=b&&11!=b?2:3;case"kw":return 1==b?0:2==b?1:3==b?2:3;case"ga":return 1==b?0:2==b?1:7>b?2:11>b?3:4;case"ar":return 0==b?0:1==b?1:2==b?2:b%100>=3&&10>=b%100?3:b%100>=11?4:5;default:return 1!=b?1:0}}}); \ No newline at end of file +angular.module("gettext",[]),angular.module("gettext").constant("gettext",function(a){return a}),angular.module("gettext").factory("gettextCatalog",["gettextPlurals","$http","$cacheFactory","$interpolate","$rootScope",function(a,b,c,d,e){function f(){e.$broadcast("gettextLanguageChanged")}function g(a){return a?"$$_ns_"+a:a}var h,i="$$noContext",j='test',k=angular.element(""+j+"").html()!==j,l=function(a){return h.debug&&h.currentLanguage!==h.baseLanguage?h.debugPrefix+a:a},m=function(a){return h.showTranslatedMarkers?h.translatedMarkerPrefix+a+h.translatedMarkerSuffix:a};return h={debug:!1,debugPrefix:"[MISSING]: ",showTranslatedMarkers:!1,translatedMarkerPrefix:"[",translatedMarkerSuffix:"]",strings:{},baseLanguage:"en",currentLanguage:"en",cache:c("strings"),setCurrentLanguage:function(a){this.currentLanguage=a,f()},getCurrentLanguage:function(){return this.currentLanguage},setStrings:function(a,b,c){this.strings[a]||(this.strings[a]={}),c=g(c),c&&!this.strings[a][c]&&(this.strings[a][c]={});for(var d in b){var e=b[d];if(k&&(d=angular.element(""+d+"").html()),angular.isString(e)||angular.isArray(e)){var h={};h[i]=e,e=h}for(var j in e){var l=e[j];e[j]=angular.isArray(l)?l:[l]}c?this.strings[a][c][d]=e:this.strings[a][d]=e}f()},getStringForm:function(a,b,c,d){var e=this.strings[this.currentLanguage]||{};d=g(d),d&&(e=e[d]||{});var f=e[a]||{},h=f[c||i]||[];return h[b]},getString:function(a,b,c,e){return a=this.getStringForm(a,0,c,e)||l(a),a=b?d(a)(b):a,m(a)},getPlural:function(b,c,e,f,g,h){var i=a(this.currentLanguage,b);return c=this.getStringForm(c,i,g,h)||l(1===b?c:e),f&&(f.$count=b,c=d(c)(f)),m(c)},loadRemote:function(a,c){return b({method:"GET",url:a,cache:h.cache}).then(function(a){var b=a.data;for(var d in b)h.setStrings(d,b[d],c);return a})}}}]),angular.module("gettext").directive("translate",["gettextCatalog","$parse","$animate","$compile","$window",function(a,b,c,d,e){function f(a,b,c){if(!a)throw new Error("You should add a "+b+" attribute whenever you add a "+c+" attribute.")}var g=function(){return String.prototype.trim?function(a){return"string"==typeof a?a.trim():a}:function(a){return"string"==typeof a?a.replace(/^\s*/,"").replace(/\s*$/,""):a}}(),h=parseInt((/msie (\d+)/.exec(angular.lowercase(e.navigator.userAgent))||[])[1],10);return{restrict:"AE",terminal:!0,compile:function(e,i){f(!i.translatePlural||i.translateN,"translate-n","translate-plural"),f(!i.translateN||i.translatePlural,"translate-plural","translate-n");var j=g(e.html()),k=i.translatePlural,l=i.translateContext,m=i.translate;return 8>=h&&""===j.slice(-13)&&(j=j.slice(0,-13)),{post:function(e,f,h){function i(){var b;k?(e=o||(o=e.$new()),e.$count=n(e),b=a.getPlural(e.$count,j,k,null,l,m)):b=a.getString(j,null,l,m);var h=f.contents();if(0!==h.length){if(b===g(h.html()))return void(p&&d(h)(e));var i=angular.element(""+b+"");d(i.contents())(e);var q=i.contents();c.enter(q,f),c.leave(h)}}var n=b(h.translateN),o=null,p=!0;h.translateN&&e.$watch(h.translateN,i),e.$on("gettextLanguageChanged",i),i(),p=!1}}}}}]),angular.module("gettext").filter("translate",["gettextCatalog",function(a){function b(b,c,d){return a.getString(b,null,c,d)}return b.$stateful=!0,b}]),angular.module("gettext").factory("gettextPlurals",function(){return function(a,b){switch(a){case"ay":case"bo":case"cgg":case"dz":case"fa":case"id":case"ja":case"jbo":case"ka":case"kk":case"km":case"ko":case"ky":case"lo":case"ms":case"my":case"sah":case"su":case"th":case"tt":case"ug":case"vi":case"wo":case"zh":return 0;case"is":return b%10!=1||b%100==11?1:0;case"jv":return 0!=b?1:0;case"mk":return 1==b||b%10==1?0:1;case"ach":case"ak":case"am":case"arn":case"br":case"fil":case"fr":case"gun":case"ln":case"mfe":case"mg":case"mi":case"oc":case"pt_BR":case"tg":case"ti":case"tr":case"uz":case"wa":case"zh":return b>1?1:0;case"lv":return b%10==1&&b%100!=11?0:0!=b?1:2;case"lt":return b%10==1&&b%100!=11?0:b%10>=2&&(10>b%100||b%100>=20)?1:2;case"be":case"bs":case"hr":case"ru":case"sr":case"uk":return b%10==1&&b%100!=11?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"mnk":return 0==b?0:1==b?1:2;case"ro":return 1==b?0:0==b||b%100>0&&20>b%100?1:2;case"pl":return 1==b?0:b%10>=2&&4>=b%10&&(10>b%100||b%100>=20)?1:2;case"cs":case"sk":return 1==b?0:b>=2&&4>=b?1:2;case"sl":return b%100==1?1:b%100==2?2:b%100==3||b%100==4?3:0;case"mt":return 1==b?0:0==b||b%100>1&&11>b%100?1:b%100>10&&20>b%100?2:3;case"gd":return 1==b||11==b?0:2==b||12==b?1:b>2&&20>b?2:3;case"cy":return 1==b?0:2==b?1:8!=b&&11!=b?2:3;case"kw":return 1==b?0:2==b?1:3==b?2:3;case"ga":return 1==b?0:2==b?1:7>b?2:11>b?3:4;case"ar":return 0==b?0:1==b?1:2==b?2:b%100>=3&&10>=b%100?3:b%100>=11?4:5;default:return 1!=b?1:0}}}); \ No newline at end of file diff --git a/src/catalog.js b/src/catalog.js index d4cf8b2..b290c35 100644 --- a/src/catalog.js +++ b/src/catalog.js @@ -29,6 +29,10 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h $rootScope.$broadcast('gettextLanguageChanged'); } + function getInternalNamespaceName(namepsace) { + return namepsace ? ('$$_ns_' + namepsace) : namepsace; + } + catalog = { debug: false, debugPrefix: '[MISSING]: ', @@ -49,11 +53,17 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h return this.currentLanguage; }, - setStrings: function (language, strings) { + setStrings: function (language, strings, namepsace) { if (!this.strings[language]) { this.strings[language] = {}; } + namepsace = getInternalNamespaceName(namepsace); + + if (namepsace && !this.strings[language][namepsace]) { + this.strings[language][namepsace] = {}; + } + for (var key in strings) { var val = strings[key]; @@ -74,28 +84,37 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h var str = val[context]; val[context] = angular.isArray(str) ? str : [str]; } - this.strings[language][key] = val; + + if (namepsace) { + this.strings[language][namepsace][key] = val; + } else { + this.strings[language][key] = val; + } } broadcastUpdated(); }, - getStringForm: function (string, n, context) { + getStringForm: function (string, n, context, namepsace) { var stringTable = this.strings[this.currentLanguage] || {}; + namepsace = getInternalNamespaceName(namepsace); + if (namepsace) { + stringTable = stringTable[namepsace] || {}; + } var contexts = stringTable[string] || {}; var plurals = contexts[context || noContext] || []; return plurals[n]; }, - getString: function (string, scope, context) { - string = this.getStringForm(string, 0, context) || prefixDebug(string); + getString: function (string, scope, context, namepsace) { + string = this.getStringForm(string, 0, context, namepsace) || prefixDebug(string); string = scope ? $interpolate(string)(scope) : string; return addTranslatedMarkers(string); }, - getPlural: function (n, string, stringPlural, scope, context) { + getPlural: function (n, string, stringPlural, scope, context, namepsace) { var form = gettextPlurals(this.currentLanguage, n); - string = this.getStringForm(string, form, context) || prefixDebug(n === 1 ? string : stringPlural); + string = this.getStringForm(string, form, context, namepsace) || prefixDebug(n === 1 ? string : stringPlural); if (scope) { scope.$count = n; string = $interpolate(string)(scope); @@ -103,7 +122,7 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h return addTranslatedMarkers(string); }, - loadRemote: function (url) { + loadRemote: function (url, namepsace) { return $http({ method: 'GET', url: url, @@ -111,7 +130,7 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h }).then(function (response) { var data = response.data; for (var lang in data) { - catalog.setStrings(lang, data[lang]); + catalog.setStrings(lang, data[lang], namepsace); } return response; }); diff --git a/src/directive.js b/src/directive.js index d01441b..006133f 100644 --- a/src/directive.js +++ b/src/directive.js @@ -31,6 +31,7 @@ angular.module('gettext').directive('translate', function (gettextCatalog, $pars var msgid = trim(element.html()); var translatePlural = attrs.translatePlural; var translateContext = attrs.translateContext; + var namespace = attrs.translate; if (msie <= 8) { // Workaround fix relating to angular adding a comment node to @@ -52,9 +53,9 @@ angular.module('gettext').directive('translate', function (gettextCatalog, $pars if (translatePlural) { scope = pluralScope || (pluralScope = scope.$new()); scope.$count = countFn(scope); - translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural, null, translateContext); + translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural, null, translateContext, namespace); } else { - translated = gettextCatalog.getString(msgid, null, translateContext); + translated = gettextCatalog.getString(msgid, null, translateContext, namespace); } var oldContents = element.contents(); diff --git a/src/filter.js b/src/filter.js index db065ee..af21316 100644 --- a/src/filter.js +++ b/src/filter.js @@ -1,6 +1,6 @@ angular.module('gettext').filter('translate', function (gettextCatalog) { - function filter(input, context) { - return gettextCatalog.getString(input, null, context); + function filter(input, context, namespace) { + return gettextCatalog.getString(input, null, context, namespace); } filter.$stateful = true; return filter;