From dfa89d04b00df7d93eec5828590ff4af16b2b81d Mon Sep 17 00:00:00 2001 From: crissdev Date: Tue, 29 Sep 2015 16:00:45 +0300 Subject: [PATCH 1/2] Improve fallback Closes #210 --- Gruntfile.js | 1 + dist/angular-gettext.js | 11 ++++++++++- dist/angular-gettext.min.js | 2 +- src/catalog.js | 11 ++++++++++- test/unit/catalog.js | 9 +++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 69e0c3d..f612bdf 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -82,6 +82,7 @@ module.exports = function (grunt) { hostname: "0.0.0.0", middleware: function (connect) { return [ + // jscs:disable requireDotNotation connect["static"](__dirname) ]; } diff --git a/dist/angular-gettext.js b/dist/angular-gettext.js index 5583459..9345c00 100644 --- a/dist/angular-gettext.js +++ b/dist/angular-gettext.js @@ -41,6 +41,14 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", $rootScope.$broadcast('gettextLanguageChanged'); } + function fallbackLanguage(lang) { + var parts = (lang || '').split('_'); + if (parts.length > 1) { + return parts[0]; + } + return null; + } + catalog = { debug: false, debugPrefix: '[MISSING]: ', @@ -93,7 +101,8 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", }, getStringForm: function (string, n, context) { - var stringTable = this.strings[this.currentLanguage] || {}; + var fallback = fallbackLanguage(this.currentLanguage); + var stringTable = this.strings[this.currentLanguage] || this.strings[fallback] || {}; var contexts = stringTable[string] || {}; var plurals = contexts[context || noContext] || []; return plurals[n]; diff --git a/dist/angular-gettext.min.js b/dist/angular-gettext.min.js index 3823944..b83a7a8 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){var b=(a||"").split("_");return b.length>1?b[0]:null}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){this.strings[a]||(this.strings[a]={});for(var c in b){var d=b[c];if(k&&(c=angular.element(""+c+"").html()),angular.isString(d)||angular.isArray(d)){var e={};e[i]=d,d=e}for(var g in d){var h=d[g];d[g]=angular.isArray(h)?h:[h]}this.strings[a][c]=d}f()},getStringForm:function(a,b,c){var d=g(this.currentLanguage),e=this.strings[this.currentLanguage]||this.strings[d]||{},f=e[a]||{},h=f[c||i]||[];return h[b]},getString:function(a,b,c){return a=this.getStringForm(a,0,c)||l(a),a=b?d(a)(b):a,m(a)},getPlural:function(b,c,e,f,g){var h=a(this.currentLanguage,b);return c=this.getStringForm(c,h,g)||l(1===b?c:e),f&&(f.$count=b,c=d(c)(f)),m(c)},loadRemote:function(a){return b({method:"GET",url:a,cache:h.cache}).then(function(a){var b=a.data;for(var c in b)h.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 diff --git a/src/catalog.js b/src/catalog.js index d4cf8b2..0024b5e 100644 --- a/src/catalog.js +++ b/src/catalog.js @@ -29,6 +29,14 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h $rootScope.$broadcast('gettextLanguageChanged'); } + function fallbackLanguage(lang) { + var parts = (lang || '').split('_'); + if (parts.length > 1) { + return parts[0]; + } + return null; + } + catalog = { debug: false, debugPrefix: '[MISSING]: ', @@ -81,7 +89,8 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h }, getStringForm: function (string, n, context) { - var stringTable = this.strings[this.currentLanguage] || {}; + var fallback = fallbackLanguage(this.currentLanguage); + var stringTable = this.strings[this.currentLanguage] || this.strings[fallback] || {}; var contexts = stringTable[string] || {}; var plurals = contexts[context || noContext] || []; return plurals[n]; diff --git a/test/unit/catalog.js b/test/unit/catalog.js index a9c355f..b636cd0 100644 --- a/test/unit/catalog.js +++ b/test/unit/catalog.js @@ -145,4 +145,13 @@ describe("Catalog", function () { assert.equal(catalog.getString("Archive", {}, "verb"), "Archiveren"); assert.equal(catalog.getString("Archive", {}, "noun"), "Archief"); }); + + it("Should return string from fallback language", function () { + var strings = { Hello: "Hallo" }; + catalog.setStrings("nl", strings); + catalog.setCurrentLanguage("nl_NL"); + // It should check strings for nl_NL, then strings for nl + assert.equal(catalog.getString("Bye"), "Bye"); + assert.equal(catalog.getString("Hello"), "Hallo"); + }); }); From 3fdb7148337425e7cc4180bc76e4e10806b1db9d Mon Sep 17 00:00:00 2001 From: crissdev Date: Wed, 28 Oct 2015 00:59:32 +0200 Subject: [PATCH 2/2] rename fallbackLanguage to baseLanguage - baseLanguage is private because it conflicts with catalog's attribute with the same name - plural detection is pretty hardcoded, there's no clear way to know if plural is defined or not --- dist/angular-gettext.js | 17 ++++++++++------- dist/angular-gettext.min.js | 2 +- src/catalog.js | 17 ++++++++++------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/dist/angular-gettext.js b/dist/angular-gettext.js index 9345c00..dd986d8 100644 --- a/dist/angular-gettext.js +++ b/dist/angular-gettext.js @@ -41,10 +41,13 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", $rootScope.$broadcast('gettextLanguageChanged'); } - function fallbackLanguage(lang) { - var parts = (lang || '').split('_'); - if (parts.length > 1) { - return parts[0]; + function baseLanguage() { + if (catalog.currentLanguage) { + var parts = catalog.currentLanguage.split('_'); + if (parts.length > 0) { + return parts[0]; + } + return catalog.currentLanguage; } return null; } @@ -101,8 +104,7 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", }, getStringForm: function (string, n, context) { - var fallback = fallbackLanguage(this.currentLanguage); - var stringTable = this.strings[this.currentLanguage] || this.strings[fallback] || {}; + var stringTable = this.strings[this.currentLanguage] || this.strings[baseLanguage()] || {}; var contexts = stringTable[string] || {}; var plurals = contexts[context || noContext] || []; return plurals[n]; @@ -115,7 +117,8 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", }, getPlural: function (n, string, stringPlural, scope, context) { - var form = gettextPlurals(this.currentLanguage, n); + var baseLang = baseLanguage(); + var form = gettextPlurals(this.currentLanguage !== 'pt_BR' ? baseLang : this.currentLanguage, n); string = this.getStringForm(string, form, context) || prefixDebug(n === 1 ? string : stringPlural); if (scope) { scope.$count = n; diff --git a/dist/angular-gettext.min.js b/dist/angular-gettext.min.js index b83a7a8..6cc16a7 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")}function g(a){var b=(a||"").split("_");return b.length>1?b[0]:null}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){this.strings[a]||(this.strings[a]={});for(var c in b){var d=b[c];if(k&&(c=angular.element(""+c+"").html()),angular.isString(d)||angular.isArray(d)){var e={};e[i]=d,d=e}for(var g in d){var h=d[g];d[g]=angular.isArray(h)?h:[h]}this.strings[a][c]=d}f()},getStringForm:function(a,b,c){var d=g(this.currentLanguage),e=this.strings[this.currentLanguage]||this.strings[d]||{},f=e[a]||{},h=f[c||i]||[];return h[b]},getString:function(a,b,c){return a=this.getStringForm(a,0,c)||l(a),a=b?d(a)(b):a,m(a)},getPlural:function(b,c,e,f,g){var h=a(this.currentLanguage,b);return c=this.getStringForm(c,h,g)||l(1===b?c:e),f&&(f.$count=b,c=d(c)(f)),m(c)},loadRemote:function(a){return b({method:"GET",url:a,cache:h.cache}).then(function(a){var b=a.data;for(var c in b)h.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(){if(h.currentLanguage){var a=h.currentLanguage.split("_");return a.length>0?a[0]:h.currentLanguage}return null}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){this.strings[a]||(this.strings[a]={});for(var c in b){var d=b[c];if(k&&(c=angular.element(""+c+"").html()),angular.isString(d)||angular.isArray(d)){var e={};e[i]=d,d=e}for(var g in d){var h=d[g];d[g]=angular.isArray(h)?h:[h]}this.strings[a][c]=d}f()},getStringForm:function(a,b,c){var d=this.strings[this.currentLanguage]||this.strings[g()]||{},e=d[a]||{},f=e[c||i]||[];return f[b]},getString:function(a,b,c){return a=this.getStringForm(a,0,c)||l(a),a=b?d(a)(b):a,m(a)},getPlural:function(b,c,e,f,h){var i=g(),j=a("pt_BR"!==this.currentLanguage?i:this.currentLanguage,b);return c=this.getStringForm(c,j,h)||l(1===b?c:e),f&&(f.$count=b,c=d(c)(f)),m(c)},loadRemote:function(a){return b({method:"GET",url:a,cache:h.cache}).then(function(a){var b=a.data;for(var c in b)h.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 diff --git a/src/catalog.js b/src/catalog.js index 0024b5e..adee5fd 100644 --- a/src/catalog.js +++ b/src/catalog.js @@ -29,10 +29,13 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h $rootScope.$broadcast('gettextLanguageChanged'); } - function fallbackLanguage(lang) { - var parts = (lang || '').split('_'); - if (parts.length > 1) { - return parts[0]; + function baseLanguage() { + if (catalog.currentLanguage) { + var parts = catalog.currentLanguage.split('_'); + if (parts.length > 0) { + return parts[0]; + } + return catalog.currentLanguage; } return null; } @@ -89,8 +92,7 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h }, getStringForm: function (string, n, context) { - var fallback = fallbackLanguage(this.currentLanguage); - var stringTable = this.strings[this.currentLanguage] || this.strings[fallback] || {}; + var stringTable = this.strings[this.currentLanguage] || this.strings[baseLanguage()] || {}; var contexts = stringTable[string] || {}; var plurals = contexts[context || noContext] || []; return plurals[n]; @@ -103,7 +105,8 @@ angular.module('gettext').factory('gettextCatalog', function (gettextPlurals, $h }, getPlural: function (n, string, stringPlural, scope, context) { - var form = gettextPlurals(this.currentLanguage, n); + var baseLang = baseLanguage(); + var form = gettextPlurals(this.currentLanguage !== 'pt_BR' ? baseLang : this.currentLanguage, n); string = this.getStringForm(string, form, context) || prefixDebug(n === 1 ? string : stringPlural); if (scope) { scope.$count = n;