From fe72601b0b705a144e51014fff1993f96aef429f Mon Sep 17 00:00:00 2001 From: alex-pex Date: Thu, 12 Dec 2013 15:54:37 +0100 Subject: [PATCH] Fixed Translator when multiple locale are loaded with dumped JS --- Resources/js/translatorTest.js | 26 +++++++++++++++++++++++++- Resources/public/js/translator.js | 12 +++++++++--- Resources/public/js/translator.min.js | 2 +- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/Resources/js/translatorTest.js b/Resources/js/translatorTest.js index 84bcf3b8..ef8364ac 100644 --- a/Resources/js/translatorTest.js +++ b/Resources/js/translatorTest.js @@ -104,7 +104,6 @@ test('guesser', function() { equal(Translator.get('boo.baz'), 'boo.baz', 'Returns the key as the key cannot be guessed'); }); - test('fromJson', function () { expect(6); @@ -120,3 +119,28 @@ test('fromJson', function () { deepEqual(Translator.defaultDomains, ['more_messages'], 'JSON parser processes defaultDomains from valid object literal'); equal(Translator.get('more_messages:moo'), 'mar', 'JSON parser processes messages from valid object literal'); }); + +test('multiple locales', function() { + expect(5); + + // Simulate i18n/messages/en.js loading + Translator.locale = 'en'; + Translator.defaultDomains = ["messages"]; + Translator.add("messages:symfony2.great", "I like Symfony2"); + Translator.add("messages:symfony2.powerful", "Symfony2 is powerful"); + + // Simulate i18n/messages/fr.js loading + Translator.locale = 'fr'; + Translator.defaultDomains = ["messages"]; + Translator.add("messages:symfony2.great", "J'aime Symfony2"); + + // Test with locale = fr + equal(Translator.get('messages:symfony2.great'), "J'aime Symfony2", 'Return translation based on current locale'); + ok(!Translator.has('messages:symfony2.powerful'), 'Translation set for another locale is not available for current locale'); + + // Test with locale = en + Translator.locale = 'en'; + equal(Translator.get('messages:symfony2.great'), "I like Symfony2", 'Return translation based on previous locale'); + ok(Translator.has('messages:symfony2.powerful'), 'Translation set for previous locale is still available'); + equal(Translator.get('messages:symfony2.powerful'), "Symfony2 is powerful", 'Return translation based on previous locale'); +}); diff --git a/Resources/public/js/translator.js b/Resources/public/js/translator.js index e76fc7f1..b3ae0fd6 100644 --- a/Resources/public/js/translator.js +++ b/Resources/public/js/translator.js @@ -367,7 +367,11 @@ var Translator = (function () { * @api public */ add: function(key, message) { - _messages[key] = message; + var _locale = Translator.locale || Translator.fallback; + if (!_messages[_locale]) { + _messages[_locale] = {}; + } + _messages[_locale][key] = message; return this; }, @@ -380,7 +384,8 @@ var Translator = (function () { * @return {String} The corresponding message if the key exists otherwise the key will be returned. */ get: function(key, placeholders, number) { - var _message = _messages[key], + var _locale = Translator.locale || Translator.fallback; + var _message = _messages[_locale][key], _number = parseInt(number, 10), _placeholders = placeholders || {}; @@ -409,7 +414,8 @@ var Translator = (function () { * @api public */ has: function(key) { - return (_messages[key] ? true : false); + var _locale = Translator.locale || Translator.fallback; + return (_messages[_locale] && _messages[_locale][key]) ? true : false; }, /** diff --git a/Resources/public/js/translator.min.js b/Resources/public/js/translator.min.js index 7bc27c59..ee56f32b 100644 --- a/Resources/public/js/translator.min.js +++ b/Resources/public/js/translator.min.js @@ -2,4 +2,4 @@ * William DURAND * MIT Licensed */ -var Translator=(function(){var f={},h=/^\w+\: +(.+)$/,d=/^\s*((\{\s*(\-?\d+[\s*,\s*\-?\d+]*)\s*\})|([\[\]])\s*(-Inf|\-?\d+)\s*,\s*(\+?Inf|\-?\d+)\s*([\[\]]))\s?(.+?)$/,i=/^\s*(\{\s*(\-?\d+[\s*,\s*\-?\d+]*)\s*\})|([\[\]])\s*(-Inf|\-?\d+)\s*,\s*(\+?Inf|\-?\d+)\s*([\[\]])/;function c(m,o){var n,j=Translator.placeHolderPrefix,l=Translator.placeHolderSuffix;for(n in o){var k=new RegExp(j+n+l,"g");if(k.test(m)){m=m.replace(k,o[n]);delete (o[n])}}return m}function b(j){var k,l=Translator.defaultDomains;if(Translator.defaultDomains.constructor!=Array){l=[Translator.defaultDomains]}for(k in l){if(Translator.has(l[k]+":"+j)){return Translator.get(l[k]+":"+j)}}return undefined}function g(o,u){var q,v,j=[],m=[],n=o.split(Translator.pluralSeparator),y=[];for(q in n){var x=n[q];var l=new RegExp(d);var t=new RegExp(h);if(l.test(x)){y=x.match(l);j[y[0]]=y[y.length-1]}else{if(t.test(x)){y=x.match(t);m.push(y[1])}else{m.push(x)}}}for(v in j){var k=new RegExp(i);if(k.test(v)){y=v.match(k);if(y[1]){var s=y[2].split(","),r;for(r in s){if(u==s[r]){return j[v]}}}else{var p=a(y[4]);var w=a(y[5]);if(("["===y[3]?u>=p:u>p)&&("]"===y[6]?u<=w:u3){j=j.split("_")[0]}switch(j){case"bo":case"dz":case"id":case"ja":case"jv":case"ka":case"km":case"kn":case"ko":case"ms":case"th":case"tr":case"vi":case"zh":return 0;case"af":case"az":case"bn":case"bg":case"ca":case"da":case"de":case"el":case"en":case"eo":case"es":case"et":case"eu":case"fa":case"fi":case"fo":case"fur":case"fy":case"gl":case"gu":case"ha":case"he":case"hu":case"is":case"it":case"ku":case"lb":case"ml":case"mn":case"mr":case"nah":case"nb":case"ne":case"nl":case"nn":case"no":case"om":case"or":case"pa":case"pap":case"ps":case"pt":case"so":case"sq":case"sv":case"sw":case"ta":case"te":case"tk":case"ur":case"zu":return(k==1)?0:1;case"am":case"bh":case"fil":case"fr":case"gun":case"hi":case"ln":case"mg":case"nso":case"xbr":case"ti":case"wa":return((k===0)||(k==1))?0:1;case"be":case"bs":case"hr":case"ru":case"sr":case"uk":return((k%10==1)&&(k%100!=11))?0:(((k%10>=2)&&(k%10<=4)&&((k%100<10)||(k%100>=20)))?1:2);case"cs":case"sk":return(k==1)?0:(((k>=2)&&(k<=4))?1:2);case"ga":return(k==1)?0:((k==2)?1:2);case"lt":return((k%10==1)&&(k%100!=11))?0:(((k%10>=2)&&((k%100<10)||(k%100>=20)))?1:2);case"sl":return(k%100==1)?0:((k%100==2)?1:(((k%100==3)||(k%100==4))?2:3));case"mk":return(k%10==1)?0:1;case"mt":return(k==1)?0:(((k===0)||((k%100>1)&&(k%100<11)))?1:(((k%100>10)&&(k%100<20))?2:3));case"lv":return(k===0)?0:(((k%10==1)&&(k%100!=11))?1:2);case"pl":return(k==1)?0:(((k%10>=2)&&(k%10<=4)&&((k%100<12)||(k%100>14)))?1:2);case"cy":return(k==1)?0:((k==2)?1:(((k==8)||(k==11))?2:3));case"ro":return(k==1)?0:(((k===0)||((k%100>0)&&(k%100<20)))?1:2);case"ar":return(k===0)?0:((k==1)?1:((k==2)?2:(((k>=3)&&(k<=10))?3:(((k>=11)&&(k<=99))?4:5))));default:return 0}}return{locale:"",fallback:"en",placeHolderPrefix:"%",placeHolderSuffix:"%",defaultDomains:[],pluralSeparator:"|",add:function(j,k){f[j]=k;return this},get:function(j,o,m){var l=f[j],k=parseInt(m,10),n=o||{};if(l===undefined){l=b(j)}if(l===undefined){l=j}if(l&&!isNaN(k)){l=g(l,k)}l=c(l,n);return l},has:function(j){return(f[j]?true:false)},fromJSON:function(l){if(typeof l==="string"){l=JSON.parse(l)}if(l.locale){this.locale=l.locale}if(l.defaultDomains){this.defaultDomains=l.defaultDomains}if(l.messages){var j;for(j in l.messages){var k=l.messages[j];this.add(j,k)}}return this}}})();if(typeof window.define==="function"&&window.define.amd){window.define("Translator",[],function(){return Translator})}; \ No newline at end of file +var Translator=function(){var _messages={},_sPluralRegex=/^\w+\: +(.+)$/,_cPluralRegex=/^\s*((\{\s*(\-?\d+[\s*,\s*\-?\d+]*)\s*\})|([\[\]])\s*(-Inf|\-?\d+)\s*,\s*(\+?Inf|\-?\d+)\s*([\[\]]))\s?(.+?)$/,_iPluralRegex=/^\s*(\{\s*(\-?\d+[\s*,\s*\-?\d+]*)\s*\})|([\[\]])\s*(-Inf|\-?\d+)\s*,\s*(\+?Inf|\-?\d+)\s*([\[\]])/;function replace_placeholders(message,placeholders){var _i,_prefix=Translator.placeHolderPrefix,_suffix=Translator.placeHolderSuffix;for(_i in placeholders){var _r=new RegExp(_prefix+_i+_suffix,"g");if(_r.test(message)){message=message.replace(_r,placeholders[_i]);delete placeholders[_i]}}return message}function guess_domain(key){var _k,_defaultDomains=Translator.defaultDomains;if(Translator.defaultDomains.constructor!=Array){_defaultDomains=[Translator.defaultDomains]}for(_k in _defaultDomains){if(Translator.has(_defaultDomains[_k]+":"+key)){return Translator.get(_defaultDomains[_k]+":"+key)}}return undefined}function pluralize(message,number){var _p,_e,_explicitRules=[],_standardRules=[],_parts=message.split(Translator.pluralSeparator),_matches=[];for(_p in _parts){var _part=_parts[_p];var _rc=new RegExp(_cPluralRegex);var _rs=new RegExp(_sPluralRegex);if(_rc.test(_part)){_matches=_part.match(_rc);_explicitRules[_matches[0]]=_matches[_matches.length-1]}else if(_rs.test(_part)){_matches=_part.match(_rs);_standardRules.push(_matches[1])}else{_standardRules.push(_part)}}for(_e in _explicitRules){var _r=new RegExp(_iPluralRegex);if(_r.test(_e)){_matches=_e.match(_r);if(_matches[1]){var _ns=_matches[2].split(","),_n;for(_n in _ns){if(number==_ns[_n]){return _explicitRules[_e]}}}else{var _leftNumber=convert_number(_matches[4]);var _rightNumber=convert_number(_matches[5]);if(("["===_matches[3]?number>=_leftNumber:number>_leftNumber)&&("]"===_matches[6]?number<=_rightNumber:number<_rightNumber)){return _explicitRules[_e]}}}}return _standardRules[plural_position(number)]||_standardRules[0]||undefined}function convert_number(number){if("-Inf"===number){return Math.log(0)}else if("+Inf"===number||"Inf"===number){return-Math.log(0)}return parseInt(number,10)}function plural_position(number){var _locale=Translator.locale||Translator.fallback;if("pt_BR"===_locale){_locale="xbr"}if(_locale.length>3){_locale=_locale.split("_")[0]}switch(_locale){case"bo":case"dz":case"id":case"ja":case"jv":case"ka":case"km":case"kn":case"ko":case"ms":case"th":case"tr":case"vi":case"zh":return 0;case"af":case"az":case"bn":case"bg":case"ca":case"da":case"de":case"el":case"en":case"eo":case"es":case"et":case"eu":case"fa":case"fi":case"fo":case"fur":case"fy":case"gl":case"gu":case"ha":case"he":case"hu":case"is":case"it":case"ku":case"lb":case"ml":case"mn":case"mr":case"nah":case"nb":case"ne":case"nl":case"nn":case"no":case"om":case"or":case"pa":case"pap":case"ps":case"pt":case"so":case"sq":case"sv":case"sw":case"ta":case"te":case"tk":case"ur":case"zu":return number==1?0:1;case"am":case"bh":case"fil":case"fr":case"gun":case"hi":case"ln":case"mg":case"nso":case"xbr":case"ti":case"wa":return number===0||number==1?0:1;case"be":case"bs":case"hr":case"ru":case"sr":case"uk":return number%10==1&&number%100!=11?0:number%10>=2&&number%10<=4&&(number%100<10||number%100>=20)?1:2;case"cs":case"sk":return number==1?0:number>=2&&number<=4?1:2;case"ga":return number==1?0:number==2?1:2;case"lt":return number%10==1&&number%100!=11?0:number%10>=2&&(number%100<10||number%100>=20)?1:2;case"sl":return number%100==1?0:number%100==2?1:number%100==3||number%100==4?2:3;case"mk":return number%10==1?0:1;case"mt":return number==1?0:number===0||number%100>1&&number%100<11?1:number%100>10&&number%100<20?2:3;case"lv":return number===0?0:number%10==1&&number%100!=11?1:2;case"pl":return number==1?0:number%10>=2&&number%10<=4&&(number%100<12||number%100>14)?1:2;case"cy":return number==1?0:number==2?1:number==8||number==11?2:3;case"ro":return number==1?0:number===0||number%100>0&&number%100<20?1:2;case"ar":return number===0?0:number==1?1:number==2?2:number>=3&&number<=10?3:number>=11&&number<=99?4:5;default:return 0}}return{locale:"",fallback:"en",placeHolderPrefix:"%",placeHolderSuffix:"%",defaultDomains:[],pluralSeparator:"|",add:function(key,message){var _locale=Translator.locale||Translator.fallback;if(!_messages[_locale]){_messages[_locale]={}}_messages[_locale][key]=message;return this},get:function(key,placeholders,number){var _locale=Translator.locale||Translator.fallback;var _message=_messages[_locale][key],_number=parseInt(number,10),_placeholders=placeholders||{};if(_message===undefined){_message=guess_domain(key)}if(_message===undefined){_message=key}if(_message&&!isNaN(_number)){_message=pluralize(_message,_number)}_message=replace_placeholders(_message,_placeholders);return _message},has:function(key){var _locale=Translator.locale||Translator.fallback;return _messages[_locale]&&_messages[_locale][key]?true:false},fromJSON:function(data){if(typeof data==="string"){data=JSON.parse(data)}if(data.locale){this.locale=data.locale}if(data.defaultDomains){this.defaultDomains=data.defaultDomains}if(data.messages){var key;for(key in data.messages){var message=data.messages[key];this.add(key,message)}}return this}}}();if(typeof window.define==="function"&&window.define.amd){window.define("Translator",[],function(){return Translator})} \ No newline at end of file