From 74282373023f6c113a2205641ee2a40be889ff77 Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Sat, 14 Mar 2015 11:11:33 +0000 Subject: [PATCH 1/7] Change localeSupported to associative array This adds the locale name to the array, thus allowing the same array to be used as input to user locale selection, or feedback. --- dist/angular-localization.js | 12 ++++++------ dist/angular-localization.min.js | 4 ++-- dist/angular-localization.min.js.gz | Bin 2067 -> 2089 bytes dist/angular-localization.min.map | 2 +- src/localization.js | 2 +- src/localization.langs.js | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/dist/angular-localization.js b/dist/angular-localization.js index 7c06438..187ce89 100644 --- a/dist/angular-localization.js +++ b/dist/angular-localization.js @@ -1,5 +1,5 @@ /** - * angular-localization :: v1.1.4 :: 2015-02-27 + * angular-localization :: v1.2.0 :: 2015-03-14 * web: https://github.com/doshprompt/angular-localization * * Copyright (c) 2015 | Rahul Doshi @@ -257,7 +257,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve if (angular.isString(value)) { value = value.trim(); - if (localeSupported.indexOf(value) != -1) { + if (localeSupported[value] != null) { lang = value; } else { lang = localeFallbacks[value.split('-')[0]] @@ -401,12 +401,12 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve } ]); angular.module('ngLocalize.InstalledLanguages', []) - .value('localeSupported', [ - 'en-US' - ]) + .value('localeSupported', { + 'en-US': "English (United States)" + }) .value('localeFallbacks', { 'en': 'en-US' }); angular.module('ngLocalize.Version', []) - .constant('localeVer', '1.1.4'); + .constant('localeVer', '1.2.0'); })(window.angular, window, document); \ No newline at end of file diff --git a/dist/angular-localization.min.js b/dist/angular-localization.min.js index bd0b322..16a3114 100644 --- a/dist/angular-localization.min.js +++ b/dist/angular-localization.min.js @@ -1,9 +1,9 @@ /** - * angular-localization :: v1.1.4 :: 2015-02-27 + * angular-localization :: v1.2.0 :: 2015-03-14 * web: https://github.com/doshprompt/angular-localization * * Copyright (c) 2015 | Rahul Doshi * License: MIT */ -!function(a){"use strict";a.module("ngLocalize.Config",[]).value("localeConf",{basePath:"languages",defaultLocale:"en-US",sharedDictionary:"common",fileExtension:".lang.json",persistSelection:!0,cookieName:"COOKIE_LOCALE_LANG",observableAttrs:new RegExp("^data-(?!ng-|i18n)"),delimiter:"::"}),a.module("ngLocalize.Events",[]).constant("localeEvents",{resourceUpdates:"ngLocalizeResourcesUpdated",localeChanges:"ngLocalizeLocaleChanged"}),a.module("ngLocalize",["ngSanitize","ngLocalize.Config","ngLocalize.Events","ngLocalize.InstalledLanguages"]).service("locale",["$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks",function(b,c,d,e,f,g,h,i,j,k){function l(a){return a&&a.length&&A.test(a)}function m(a){var b=a?a.split("."):"",c="";return b.length>1&&(c=b.slice(0,-1).join(".")),c}function n(a){var b=a?a.split("."):[],c="";return b.length&&(c=b[b.length-1]),c}function o(a){var b,c=null,d=a?a.split("."):[];if(d.length>1)for(c=y,b=0;b1){for(b=0;b1?(f=[],c.forEach(function(a){f.push(q(a))}),e=d.all(f)):e=q(b),e}function s(b,c){var d=b,e=0;return c&&(a.isArray(c)?a.forEach(c,function(a,b){d=d.replace("%"+(b+1),a),d=d.replace("{"+(b+1)+"}",a)}):a.forEach(c,function(a,b){++e,d=d.replace("{"+b+"}",a),d=d.replace("%"+b,a),d=d.replace("%"+e,a),d=d.replace("{"+e+"}",a)})),d=d.replace(/\n/g,"
")}function t(b,c){var d,f,g,i="",j=!1;return a.isString(b)&&!c&&-1!=b.indexOf(h.delimiter)&&(g=b.split(h.delimiter),b=g[0],c=a.fromJson(g[1])),j=l(b),j?(a.isObject(c)||(c=[c]),d=o(b),d&&!d._loading?(f=n(b),d[f]?i=s(d[f],c):(e.info("[localizationService] Key not found: "+b),i="%%KEY_NOT_FOUND%%")):d||p(b)):i=b,i}function u(b){var c;a.isString(b)?(b=b.trim(),-1!=j.indexOf(b)?c=b:(c=k[b.split("-")[0]],a.isUndefined(c)&&(c=h.defaultLocale))):c=h.defaultLocale,c!=w&&(y={},x={},w=c,f.$broadcast(i.localeChanges,w),f.$broadcast(i.resourceUpdates),z&&z.put(h.cookieName,c))}function v(){return w}var w,x,y,z,A=new RegExp("^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$");return h.persistSelection&&b.has("$cookieStore")&&(z=b.get("$cookieStore")),u(z?z.get(h.cookieName):g.navigator.userLanguage||g.navigator.language),{ready:r,isToken:l,getPath:m,getKey:n,setLocale:u,getLocale:v,getString:t}}]).filter("i18n",["locale",function(a){return function(b,c){return a.getString(b,c)}}]).directive("i18n",["$sce","locale","localeEvents","localeConf",function(b,c,d,e){function f(a,c){c!==a.html()&&a.html(b.getTrustedHtml(c))}function g(a,b,d){c.isToken(b)?c.ready(c.getPath(b)).then(function(){f(a,c.getString(b,d))}):f(a,b)}return function(b,c,f){var h;f.$observe("i18n",function(a,b){a&&a!=b&&g(c,a,h)}),a.forEach(f.$attr,function(a,b){e.observableAttrs.test(a)&&f.$observe(b,function(a,d){(a&&a!=d||!h||!h[b])&&(h=h||{},h[b]=f[b],g(c,f.i18n,h))})}),b.$on(d.resourceUpdates,function(){g(c,f.i18n,h)}),b.$on(d.localeChanges,function(){g(c,f.i18n,h)})}}]).directive("i18nAttr",["locale","localeEvents",function(a,b){return function(c,d,e){function f(b,d){var f,h=c.$eval(d),i=[];for(var j in h)f=h[j],a.isToken(f)&&-1==i.indexOf(a.getPath(f))&&i.push(a.getPath(f));a.ready(i).then(function(){var b="";for(var c in h)f=h[c],b=a.getString(f),g[c]!==b&&e.$set(c,g[c]=b)})}var g={};e.$observe("i18nAttr",function(a,b){a&&a!=b&&f(d,a)}),c.$on(b.resourceUpdates,function(){f(d,e.i18nAttr)}),c.$on(b.localeChanges,function(){f(d,e.i18nAttr)})}}]),a.module("ngLocalize.InstalledLanguages",[]).value("localeSupported",["en-US"]).value("localeFallbacks",{en:"en-US"}),a.module("ngLocalize.Version",[]).constant("localeVer","1.1.4")}(window.angular,window,document); +!function(a){"use strict";a.module("ngLocalize.Config",[]).value("localeConf",{basePath:"languages",defaultLocale:"en-US",sharedDictionary:"common",fileExtension:".lang.json",persistSelection:!0,cookieName:"COOKIE_LOCALE_LANG",observableAttrs:new RegExp("^data-(?!ng-|i18n)"),delimiter:"::"}),a.module("ngLocalize.Events",[]).constant("localeEvents",{resourceUpdates:"ngLocalizeResourcesUpdated",localeChanges:"ngLocalizeLocaleChanged"}),a.module("ngLocalize",["ngSanitize","ngLocalize.Config","ngLocalize.Events","ngLocalize.InstalledLanguages"]).service("locale",["$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks",function(b,c,d,e,f,g,h,i,j,k){function l(a){return a&&a.length&&A.test(a)}function m(a){var b=a?a.split("."):"",c="";return b.length>1&&(c=b.slice(0,-1).join(".")),c}function n(a){var b=a?a.split("."):[],c="";return b.length&&(c=b[b.length-1]),c}function o(a){var b,c=null,d=a?a.split("."):[];if(d.length>1)for(c=y,b=0;b1){for(b=0;b1?(f=[],c.forEach(function(a){f.push(q(a))}),e=d.all(f)):e=q(b),e}function s(b,c){var d=b,e=0;return c&&(a.isArray(c)?a.forEach(c,function(a,b){d=d.replace("%"+(b+1),a),d=d.replace("{"+(b+1)+"}",a)}):a.forEach(c,function(a,b){++e,d=d.replace("{"+b+"}",a),d=d.replace("%"+b,a),d=d.replace("%"+e,a),d=d.replace("{"+e+"}",a)})),d=d.replace(/\n/g,"
")}function t(b,c){var d,f,g,i="",j=!1;return a.isString(b)&&!c&&-1!=b.indexOf(h.delimiter)&&(g=b.split(h.delimiter),b=g[0],c=a.fromJson(g[1])),j=l(b),j?(a.isObject(c)||(c=[c]),d=o(b),d&&!d._loading?(f=n(b),d[f]?i=s(d[f],c):(e.info("[localizationService] Key not found: "+b),i="%%KEY_NOT_FOUND%%")):d||p(b)):i=b,i}function u(b){var c;a.isString(b)?(b=b.trim(),null!=j[b]?c=b:(c=k[b.split("-")[0]],a.isUndefined(c)&&(c=h.defaultLocale))):c=h.defaultLocale,c!=w&&(y={},x={},w=c,f.$broadcast(i.localeChanges,w),f.$broadcast(i.resourceUpdates),z&&z.put(h.cookieName,c))}function v(){return w}var w,x,y,z,A=new RegExp("^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$");return h.persistSelection&&b.has("$cookieStore")&&(z=b.get("$cookieStore")),u(z?z.get(h.cookieName):g.navigator.userLanguage||g.navigator.language),{ready:r,isToken:l,getPath:m,getKey:n,setLocale:u,getLocale:v,getString:t}}]).filter("i18n",["locale",function(a){return function(b,c){return a.getString(b,c)}}]).directive("i18n",["$sce","locale","localeEvents","localeConf",function(b,c,d,e){function f(a,c){c!==a.html()&&a.html(b.getTrustedHtml(c))}function g(a,b,d){c.isToken(b)?c.ready(c.getPath(b)).then(function(){f(a,c.getString(b,d))}):f(a,b)}return function(b,c,f){var h;f.$observe("i18n",function(a,b){a&&a!=b&&g(c,a,h)}),a.forEach(f.$attr,function(a,b){e.observableAttrs.test(a)&&f.$observe(b,function(a,d){(a&&a!=d||!h||!h[b])&&(h=h||{},h[b]=f[b],g(c,f.i18n,h))})}),b.$on(d.resourceUpdates,function(){g(c,f.i18n,h)}),b.$on(d.localeChanges,function(){g(c,f.i18n,h)})}}]).directive("i18nAttr",["locale","localeEvents",function(a,b){return function(c,d,e){function f(b,d){var f,h=c.$eval(d),i=[];for(var j in h)f=h[j],a.isToken(f)&&-1==i.indexOf(a.getPath(f))&&i.push(a.getPath(f));a.ready(i).then(function(){var b="";for(var c in h)f=h[c],b=a.getString(f),g[c]!==b&&e.$set(c,g[c]=b)})}var g={};e.$observe("i18nAttr",function(a,b){a&&a!=b&&f(d,a)}),c.$on(b.resourceUpdates,function(){f(d,e.i18nAttr)}),c.$on(b.localeChanges,function(){f(d,e.i18nAttr)})}}]),a.module("ngLocalize.InstalledLanguages",[]).value("localeSupported",{"en-US":"English (United States)"}).value("localeFallbacks",{en:"en-US"}),a.module("ngLocalize.Version",[]).constant("localeVer","1.2.0")}(window.angular,window,document); //# sourceMappingURL=angular-localization.min.map \ No newline at end of file diff --git a/dist/angular-localization.min.js.gz b/dist/angular-localization.min.js.gz index 233b8b65e901c5844b59a1a3eea1509e631f0ee9..4c9e0b615fc336b0d03c1656bf2e63d5951d8723 100644 GIT binary patch delta 2077 zcmV+&2;%pX5UCJdH8Jkwugynq_H^L-C6^r>9@ehkxsz|D`|tE3IED$I`-oqFChCU=Tz_SUSQ@=L0Xz z!$p?P7scR|NNlCuAJWBh76oCUnJ%j&YisSh49i&i2mukTxr$ts| z*`st~bx{;qZY64|eOJNd)56sM6WE$7(eNX z%SV+IdF=`}P4Yq}#m*bMxmBj}w9H&}yMQ8gqTzb`-@ZK^A zmSA)vlc=ahr^0s1{`R}ibc{Gw-c=JloQ~WF-0TiVin>uULj=+c`@4i#`u~%D;*|7s zvotL=ZrpT1hIE%v;-yPGwXt&Ks_pQmTrAS8a>w?~Cm7^N_W^4ftUBD~9#`Dw0S|e^ zXZ(S!c9Ssz8Go9!b6Wc-GtIH(Sc-fRM~I@(nWgL8wRL^8736HC{5CWU)3qIu$K;c9 z-XAhCOQWRP#kjkdoxCY~GCe7~mOR-F`@`vhytI*r-ANh8+W#+Dt6y&bO%fY$=3o7th* zaY0WX=)L8UT`Mx|q)|bwcfB^ZPxcCk5A5xT&w4fqq`@c<_i-w{C<$nJGqAx5SQd%{ zCgH9KRAJ5l=+Z^r<>nqw^?3j)n*cGYyrxBn40A*%^Xp~uEd!Xd;u+kEFa;BLib%Or zHUe9yLVsy{?c5h#C&RNV0k%jSaRB2_6K`r5^jpovkIMAeh6$Br(AyZrR%-i7pS0=z zrcTGH_DSM+o>rt9X|^=IH>=3&(3}lpn|#AWR|mDFLt{H6|pE+dvmhA>ygcb z5hrwGO^GXjj!Wr=X1jFyVo~Oy zNs~qd5P!E$ofCo8=k{y|i_dqVaDlD;*<6O?+G%t5^d~vI=0QcK7O^B|KGS=q(;K2P z00HfZ)pnw%Z*)v})skV|C7{m+F*$)#yH)8{8#>fa||H*>8G_k&Bjd zDuR!|lpvJOu)%8^B0wLU)*p6&6qFhDbnTm=Xn#t0m8=bj+7p0vFgYh8hDU(Qf1<%a zUW0QPw8a#%*|-YEwL`TI(E$2go01;qNNIrw?cN^y07z23p7_&oWalP5;4qe{V4I)5 zmB?SzvzDZV=BH&+#Cr|a9VAJ5KEUo4OE381$kASc?pt!y%B zbbsKVF<90S7|l(_iQqf-4AeOW#4ViWVbUa6UuW>gl+*TGc+!s&<<)fO+T^)b7sp`0 ztC!sE*h{Q_24nLl`dQlUF&iEbN{RAR*( zLaSDLPEUZ4mGE5cy6lo(Zl53Nxdwz)Y&PiVP#2K`rcNC%wR5}1uFYs$FSL8EeScRa z8j02WN~i~x#Zu6IBe$Eos%hljYWeDR@VK{Y^>Zi+q#Ni$s)ofpHW_tw)l=p6A6c1$ zzW+fl4uBC5v2hQ3#nx|>5pG=>%&H$C7g9b66o;f;d@HR7=k$o$Ex#hm%?bB#zs|sL z1Webrj>Z>rml#t#7*UBj}k{0nO!q$7%g>9dlwFF)~di7 zosj;J`h?fe#s~>YW823MCrf-m#=;!f1B)DpO-%1NC3(w92fJEZ4zv924X1!ZhiilK z2sMXZIS#{X>{Rimu=qT*UC~vzx1!$y!J=8FMvvxZ)a-@Kx5LS-X22RPK7XUyV%t$u zTVw+o)ON#&>bigM76e=aEP9Qq`Z|Etf2Y~qYj&roN$u3~(f8sla1W>`(M5XWfOYRl z&ZGSScy^?Y@K(F<4a}hruc|T7O~G>hSA1!$5<8LYO>ai{)fS5J=_~Y!>*nh(3#}XB zYWwZL(l3($y;`W5x47=2aay}6s$zk=@!{sy<#7el-0pwtO8+n7d-}|9>Q0YIV6pmg zgLcKN@3dn3J%-mq?xk)y2Ts}OPwxhUKWnvP|B#CX;(7c1%0Bh|M$9Ap$;E#G;uHB6 HHWB~;mhm*D delta 2055 zcmV+i2>AD@5R(vpABzY80000000V_sZExGi5&j;a|AA&@f*Y+?R&YfN>Uf5cIM+13 zIEdo{g{%fka`_@tq{0`=wxs`l&yW;F$#VO_GMBqMGduIlGqW7NefvgxtH~rNW0?)& z)Rl4cEQ=^jG|SQ+Mq(s>p{I9eqrVN#-VNUUoz^dvV`*W3Q7m$6I1Hj9EFIyd^P!jK z;UY`ti(+_8B(~D-_vzv(i-NGwOqW%XwYBz5hGndMfPjeBTt%)*a%E|MeEN>@@Xd)| zCN2pvC0prbuC%|HkmqiBrDrFSWAe!v zAB>oorBPDtV%*)yPF|HgnI4s0OP*|pgVA(PUfRmT?xc)k?!6Q|j(pQ=ZDoF%LFN;8 z?6a}+tJg{%JN-UeVeN@K@g~l6%2u_^v6Crzzj5v6{ePyhv17+#XU7Wz;I#niW_BpH zT+r8tdVhIf*NO}~YE)3`U9ZjN$zB2Rf!&PwtZ$P*8jJ(+BTl6kB>^pO2R2v%%R;fo zB-|B&D$E%GUAoA-+}z=*J`X@;6ClQw*R%+cVU7r8e!Wb-W&m?mJb_ygreNYu5h-`d z#$XFoD1U9Io%^EaWO#NZz!r%E4q*Io;!O>Meyh3oL75)gFrl&xdRwE|N;R+aNtf<# z>U5lHA0>|GX+^4$W=qrivx>a-&Dk)v*~RW>2SZ!={16=-SIMV84YT2zEty3~l)FKc(z!~rX$_oQX&XBojD zO`)Kw3`JS1c4{fKqTm@x)XqPFgYV4hDU(Qf1$xZ zUW0QPw8a#%*?AR=Ylmtbq5<@~HYGjIk^5OIp^~Lfip8$F*0&=3A+sZbR z#(#VMIS0!+0;9RfIJs%ox(Sm2x`i{{Puesa=nP(&auRZjg?^MMuO>a$CjWJMIR-Oc zyyWhQy~OG#@HT&>pQY^{a^haA!Exhi zc$!Mg!3^W2`F#FdO?Ay@Rv;4j5CszJ1bXjm+jgzj-I;AG&8VLQrCAw|^6%-rO01Ye zXw`7f=?Orx5}vDVuU*p1=J|o1YgkytW`n*C)e(tc>eTmAQ@3sJy1dqSq1$=wdVed? zO03>jLOpOTmV*3SxxL&~Z9Df`<5xF@haFz0t3zoZ-9Q%-HZ10`$*8xho+`J0&&nJm z{!eH6-``eL7NsW$~}8AbpqmONxtXMf*T7txcruN>@A;@~>7ZD|doqt5B>!okg26}aOh zq(AgdgxAo<2nkAK+s6+lOMF4b!W`HGiyVkeOz$uydB;h6yEw@wC zHTzyU48u$8RPm><_&l^-(Nnm+qU!?9qGhIbkLG67@`cQ|!^x~>z#1(+qkjrx+fhrM zvIPw)ykSIj_1}978m<8ry+l=gDZm9_tJ&RYcBiOJ-PH2Y{o*Zf52z^7Lwe(Ybq7k$ zqx}JRcB~HYR=e;O%%K~vYBJDG!E*jrd}*x`Tan#OuSWRA7K-uli}aC8=gaR4oqOS= z`GRn`q;pYRff}1tuU+5&O+>6tpA?SW-!TcqRbOe)nwa(dRW#pTcs=A^>Xvh$k&XZI lW;pz-R=e*HxmX}-x8JVpW8Z4TJi?z`{0XA;O$#Ct006s}A=Cf> diff --git a/dist/angular-localization.min.map b/dist/angular-localization.min.map index 4b087fe..07ed7b0 100644 --- a/dist/angular-localization.min.map +++ b/dist/angular-localization.min.map @@ -1 +1 @@ -{"version":3,"file":"angular-localization.min.js","sources":["angular-localization.js"],"names":["angular","module","value","basePath","defaultLocale","sharedDictionary","fileExtension","persistSelection","cookieName","observableAttrs","RegExp","delimiter","constant","resourceUpdates","localeChanges","service","$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks","isToken","str","length","TOKEN_REGEX","test","getPath","tok","path","split","result","slice","join","getKey","getBundle","i","bundles","loadBundle","token","root","url","currentLocale","_loading","get","success","data","key","hasOwnProperty","$broadcast","deferrences","resolve","error","bundleReady","bundle","langFile","defer","promise","ready","paths","deferred","outstanding","isString","isArray","Error","forEach","push","all","applySubstitutions","text","subs","res","firstOfKind","sub","replace","v","k","getLocalizedString","txt","A","isValidToken","indexOf","fromJson","isObject","info","setLocale","lang","trim","isUndefined","cookieStore","put","getLocale","has","navigator","userLanguage","language","getString","filter","locale","input","args","directive","$sce","setText","elm","tag","html","getTrustedHtml","update","string","optArgs","then","scope","attrs","hasObservers","$observe","newVal","oldVal","$attr","attr","normAttr","i18n","$on","elem","updateText","target","attributes","exp","values","$eval","langFiles","lastValues","$set","i18nAttr","en","window","document"],"mappings":"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","sourceRoot":"/Users/r.doshi/Projects/angular-localization"} \ No newline at end of file +{"version":3,"file":"angular-localization.min.js","sources":["angular-localization.js"],"names":["angular","module","value","basePath","defaultLocale","sharedDictionary","fileExtension","persistSelection","cookieName","observableAttrs","RegExp","delimiter","constant","resourceUpdates","localeChanges","service","$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks","isToken","str","length","TOKEN_REGEX","test","getPath","tok","path","split","result","slice","join","getKey","getBundle","i","bundles","loadBundle","token","root","url","currentLocale","_loading","get","success","data","key","hasOwnProperty","$broadcast","deferrences","resolve","error","bundleReady","bundle","langFile","defer","promise","ready","paths","deferred","outstanding","isString","isArray","Error","forEach","push","all","applySubstitutions","text","subs","res","firstOfKind","sub","replace","v","k","getLocalizedString","txt","A","isValidToken","indexOf","fromJson","isObject","info","setLocale","lang","trim","isUndefined","cookieStore","put","getLocale","has","navigator","userLanguage","language","getString","filter","locale","input","args","directive","$sce","setText","elm","tag","html","getTrustedHtml","update","string","optArgs","then","scope","attrs","hasObservers","$observe","newVal","oldVal","$attr","attr","normAttr","i18n","$on","elem","updateText","target","attributes","exp","values","$eval","langFiles","lastValues","$set","i18nAttr","en-US","en","window","document"],"mappings":"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","sourceRoot":"/Users/chris/Development/angular-localization"} \ No newline at end of file diff --git a/src/localization.js b/src/localization.js index a868689..e7d96d2 100644 --- a/src/localization.js +++ b/src/localization.js @@ -232,7 +232,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve if (angular.isString(value)) { value = value.trim(); - if (localeSupported.indexOf(value) != -1) { + if (localeSupported[value] != null) { lang = value; } else { lang = localeFallbacks[value.split('-')[0]] diff --git a/src/localization.langs.js b/src/localization.langs.js index 0b5e2bc..fef19e9 100644 --- a/src/localization.langs.js +++ b/src/localization.langs.js @@ -1,7 +1,7 @@ angular.module('ngLocalize.InstalledLanguages', []) - .value('localeSupported', [ - 'en-US' - ]) + .value('localeSupported', { + 'en-US': "English (United States)" + }) .value('localeFallbacks', { 'en': 'en-US' }); \ No newline at end of file From f6231f1b909077e511ff26c1e07494764c7c2aa5 Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Sat, 14 Mar 2015 15:16:40 +0000 Subject: [PATCH 2/7] Add fallback code from @jamescarter-le and fix to pass tests --- src/localization.js | 60 ++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/src/localization.js b/src/localization.js index e7d96d2..de3f43a 100644 --- a/src/localization.js +++ b/src/localization.js @@ -3,6 +3,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve function ($injector, $http, $q, $log, $rootScope, $window, localeConf, localeEvents, localeSupported, localeFallbacks) { var TOKEN_REGEX = new RegExp('^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$'), currentLocale, + languageBundles, deferrences, bundles, cookieStore; @@ -37,13 +38,13 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } - function getBundle(tok) { + function getBundle(tok, lang) { var result = null, path = tok ? tok.split('.') : [], i; if (path.length > 1) { - result = bundles; + result = languageBundles[lang]; for (i = 0; i < path.length - 1; i++) { if (result[path[i]]) { @@ -58,10 +59,10 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } - function loadBundle(token) { + function loadBundle(token, lang) { var path = token ? token.split('.') : '', - root = bundles, - url = localeConf.basePath + '/' + currentLocale, + root = languageBundles[lang], + url = localeConf.basePath + '/' + lang, i; if (path.length > 1) { @@ -117,7 +118,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve path = path || localeConf.langFile; token = path + "._LOOKUP_"; - bundle = getBundle(token); + bundle = getBundle(token, currentLocale); if (!deferrences[path]) { deferrences[path] = $q.defer(); @@ -127,7 +128,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve deferrences[path].resolve(path); } else { if (!bundle) { - loadBundle(token); + loadBundle(token, currentLocale); } } @@ -186,13 +187,18 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return res; } - function getLocalizedString(txt, subs) { + function getLocalizedString(txt, subs, locale) { var result = '', bundle, key, A, isValidToken = false; + var useLocale = currentLocale; + if (locale != null) { + useLocale = locale; + } + if (angular.isString(txt) && !subs && txt.indexOf(localeConf.delimiter) != -1) { A = txt.split(localeConf.delimiter); txt = A[0]; @@ -205,19 +211,23 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve subs = [subs]; } - bundle = getBundle(txt); + bundle = getBundle(txt, useLocale); if (bundle && !bundle._loading) { key = getKey(txt); if (bundle[key]) { result = applySubstitutions(bundle[key], subs); } else { - $log.info("[localizationService] Key not found: " + txt); - result = "%%KEY_NOT_FOUND%%"; + if (currentLocale != localeConf.defaultLocale && useLocale != localeConf.defaultLocale) { + result = getLocalizedString(txt, subs, localeConf.defaultLocale); + } else { + $log.info("[localizationService] Key not found: " + txt); + result = "%%KEY_NOT_FOUND%%"; + } } } else { if (!bundle) { - loadBundle(txt); + loadBundle(txt, useLocale); } } } else { @@ -229,23 +239,23 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve function setLocale(value) { var lang; - - if (angular.isString(value)) { - value = value.trim(); - if (localeSupported[value] != null) { - lang = value; - } else { - lang = localeFallbacks[value.split('-')[0]] - if (angular.isUndefined(lang)) { - lang = localeConf.defaultLocale; - } - } - } else { + if(!angular.isString(value)) { lang = localeConf.defaultLocale; } + else { + value = value.trim(); + lang = localeSupported[value] ? value : + localeFallbacks[value.split('-')[0]] || localeConf.defaultLocale; + } + + if (languageBundles == null) { + languageBundles = {}; + angular.forEach(localeSupported, function(value, key) { + languageBundles[key] = {}; + }); + } if (lang != currentLocale) { - bundles = {}; deferrences = {}; currentLocale = lang; From 52e003ea04661bb63bfd9c5f26d92e689d545242 Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Sat, 14 Mar 2015 18:56:53 +0000 Subject: [PATCH 3/7] Add hierarchical fallback This allows three levels of fallback. The requested locale, falling back to the fallback locale and then the default. This allows incremental localisation files, so, for example, you can have de-CH as a swiss localisisation, overiding de-DE for the main German localisation, and then the fallback of en-US for anything not in these files. --- dist/angular-localization.js | 149 ++++++++++++++++++++-------- dist/angular-localization.min.js | 2 +- dist/angular-localization.min.js.gz | Bin 2089 -> 2232 bytes dist/angular-localization.min.map | 2 +- src/localization.js | 117 +++++++++++++++------- tests/unit/directiveSpec.js | 28 +++++- 6 files changed, 214 insertions(+), 84 deletions(-) diff --git a/dist/angular-localization.js b/dist/angular-localization.js index 187ce89..ec0473c 100644 --- a/dist/angular-localization.js +++ b/dist/angular-localization.js @@ -28,6 +28,8 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve function ($injector, $http, $q, $log, $rootScope, $window, localeConf, localeEvents, localeSupported, localeFallbacks) { var TOKEN_REGEX = new RegExp('^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$'), currentLocale, + locales = [], + languageBundles, deferrences, bundles, cookieStore; @@ -62,13 +64,13 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } - function getBundle(tok) { + function getBundle(tok, lang) { var result = null, path = tok ? tok.split('.') : [], i; if (path.length > 1) { - result = bundles; + result = languageBundles[lang]; for (i = 0; i < path.length - 1; i++) { if (result[path[i]]) { @@ -83,10 +85,10 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } - function loadBundle(token) { + function loadBundle(token, lang) { var path = token ? token.split('.') : '', - root = bundles, - url = localeConf.basePath + '/' + currentLocale, + root = languageBundles[lang], + url = localeConf.basePath + '/' + lang, i; if (path.length > 1) { @@ -135,14 +137,14 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve } } - function bundleReady(path) { + function bundleReady(path, locale) { var bundle, token; path = path || localeConf.langFile; token = path + "._LOOKUP_"; - bundle = getBundle(token); + bundle = getBundle(token, locale); if (!deferrences[path]) { deferrences[path] = $q.defer(); @@ -152,7 +154,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve deferrences[path].resolve(path); } else { if (!bundle) { - loadBundle(token); + loadBundle(token, locale); } } @@ -172,16 +174,22 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve throw new Error("locale.ready requires either an Array or comma-separated list."); } + outstanding = []; if (paths.length > 1) { - outstanding = []; paths.forEach(function (path) { - outstanding.push(bundleReady(path)); + // Load all bundles that may be required by the fallback hierarchy + for (var i = 0; i < locales.length; i++) { + outstanding.push(bundleReady(path, locales[i])); + } }); - deferred = $q.all(outstanding); } else { - deferred = bundleReady(path); + // Load all bundles that may be required by the fallback hierarchy + for (var i = 0; i < locales.length; i++) { + outstanding.push(bundleReady(path, locales[i])); + } } + deferred = $q.all(outstanding); return deferred; } @@ -212,7 +220,24 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve } function getLocalizedString(txt, subs) { - var result = '', + var bundle, + key, + A, + isValidToken = false; + + for (var i = 0; i < locales.length; i++) { + var result = getStringForLocale(txt, subs, locales[i]); + if(result != null) { + return result; + } + } + + $log.info("[localizationService] Key not found: " + txt); + return "%%KEY_NOT_FOUND%%"; + } + + function getStringForLocale(txt, subs, locale) { + var result = null, bundle, key, A, @@ -224,56 +249,82 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve subs = angular.fromJson(A[1]); } + // If the token isn't valid, then just return it isValidToken = isToken(txt); - if (isValidToken) { - if (!angular.isObject(subs)) { - subs = [subs]; - } + if (!isValidToken) { + return txt; + } - bundle = getBundle(txt); - if (bundle && !bundle._loading) { - key = getKey(txt); + if (!angular.isObject(subs)) { + subs = [subs]; + } - if (bundle[key]) { - result = applySubstitutions(bundle[key], subs); - } else { - $log.info("[localizationService] Key not found: " + txt); - result = "%%KEY_NOT_FOUND%%"; - } - } else { - if (!bundle) { - loadBundle(txt); - } + // Load the file + bundle = getBundle(txt, locale); + if (bundle && !bundle._loading) { + key = getKey(txt); + + if (bundle[key]) { + return applySubstitutions(bundle[key], subs); } } else { - result = txt; + if (!bundle) { + loadBundle(txt, locale); + } } - return result; + return null; } function setLocale(value) { var lang; + var fall; - if (angular.isString(value)) { + if(!angular.isString(value)) { + lang = localeConf.defaultLocale; + } + else { value = value.trim(); - if (localeSupported[value] != null) { + + // Get the fallback first - if it's not valid, then use the default + if(localeSupported[localeFallbacks[value.split('-')[0]]] != null) { + fall = localeFallbacks[value.split('-')[0]]; + } + else { + fall = localeConf.defaultLocale; + } + + // Check if the requested locale is supported - if not, use the fallback + if(localeSupported[value] != null) { lang = value; - } else { - lang = localeFallbacks[value.split('-')[0]] - if (angular.isUndefined(lang)) { - lang = localeConf.defaultLocale; - } } - } else { - lang = localeConf.defaultLocale; + else { + lang = fall; + fall = localeConf.defaultLocale; + } + } + + if (languageBundles == null) { + languageBundles = {}; + angular.forEach(localeSupported, function(value, key) { + languageBundles[key] = {}; + }); } if (lang != currentLocale) { - bundles = {}; deferrences = {}; currentLocale = lang; + // Create the locales list. + locales = []; + if(lang != localeConf.defaultLocale) { + locales.push(lang); + } + if(fall != localeConf.defaultLocale) { + locales.push(fall); + } + locales.push(localeConf.defaultLocale); + $rootScope.$broadcast(localeEvents.localeChanges, currentLocale); $rootScope.$broadcast(localeEvents.resourceUpdates); @@ -400,13 +451,25 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve }; } ]); -angular.module('ngLocalize.InstalledLanguages', []) +/*angular.module('ngLocalize.InstalledLanguages', []) .value('localeSupported', { 'en-US': "English (United States)" }) .value('localeFallbacks', { 'en': 'en-US' }); +*/ +angular.module('ngLocalize.InstalledLanguages', []) +.value('localeSupported', { + 'en-US': "English (United States)", + 'aa-XX': "English (XX)", + 'aa-YY': "English (YY)" +}) + +.value('localeFallbacks', { + 'en': 'en-US', + 'aa': 'aa-XX' +}); angular.module('ngLocalize.Version', []) .constant('localeVer', '1.2.0'); })(window.angular, window, document); \ No newline at end of file diff --git a/dist/angular-localization.min.js b/dist/angular-localization.min.js index 16a3114..fa7e48c 100644 --- a/dist/angular-localization.min.js +++ b/dist/angular-localization.min.js @@ -5,5 +5,5 @@ * Copyright (c) 2015 | Rahul Doshi * License: MIT */ -!function(a){"use strict";a.module("ngLocalize.Config",[]).value("localeConf",{basePath:"languages",defaultLocale:"en-US",sharedDictionary:"common",fileExtension:".lang.json",persistSelection:!0,cookieName:"COOKIE_LOCALE_LANG",observableAttrs:new RegExp("^data-(?!ng-|i18n)"),delimiter:"::"}),a.module("ngLocalize.Events",[]).constant("localeEvents",{resourceUpdates:"ngLocalizeResourcesUpdated",localeChanges:"ngLocalizeLocaleChanged"}),a.module("ngLocalize",["ngSanitize","ngLocalize.Config","ngLocalize.Events","ngLocalize.InstalledLanguages"]).service("locale",["$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks",function(b,c,d,e,f,g,h,i,j,k){function l(a){return a&&a.length&&A.test(a)}function m(a){var b=a?a.split("."):"",c="";return b.length>1&&(c=b.slice(0,-1).join(".")),c}function n(a){var b=a?a.split("."):[],c="";return b.length&&(c=b[b.length-1]),c}function o(a){var b,c=null,d=a?a.split("."):[];if(d.length>1)for(c=y,b=0;b1){for(b=0;b1?(f=[],c.forEach(function(a){f.push(q(a))}),e=d.all(f)):e=q(b),e}function s(b,c){var d=b,e=0;return c&&(a.isArray(c)?a.forEach(c,function(a,b){d=d.replace("%"+(b+1),a),d=d.replace("{"+(b+1)+"}",a)}):a.forEach(c,function(a,b){++e,d=d.replace("{"+b+"}",a),d=d.replace("%"+b,a),d=d.replace("%"+e,a),d=d.replace("{"+e+"}",a)})),d=d.replace(/\n/g,"
")}function t(b,c){var d,f,g,i="",j=!1;return a.isString(b)&&!c&&-1!=b.indexOf(h.delimiter)&&(g=b.split(h.delimiter),b=g[0],c=a.fromJson(g[1])),j=l(b),j?(a.isObject(c)||(c=[c]),d=o(b),d&&!d._loading?(f=n(b),d[f]?i=s(d[f],c):(e.info("[localizationService] Key not found: "+b),i="%%KEY_NOT_FOUND%%")):d||p(b)):i=b,i}function u(b){var c;a.isString(b)?(b=b.trim(),null!=j[b]?c=b:(c=k[b.split("-")[0]],a.isUndefined(c)&&(c=h.defaultLocale))):c=h.defaultLocale,c!=w&&(y={},x={},w=c,f.$broadcast(i.localeChanges,w),f.$broadcast(i.resourceUpdates),z&&z.put(h.cookieName,c))}function v(){return w}var w,x,y,z,A=new RegExp("^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$");return h.persistSelection&&b.has("$cookieStore")&&(z=b.get("$cookieStore")),u(z?z.get(h.cookieName):g.navigator.userLanguage||g.navigator.language),{ready:r,isToken:l,getPath:m,getKey:n,setLocale:u,getLocale:v,getString:t}}]).filter("i18n",["locale",function(a){return function(b,c){return a.getString(b,c)}}]).directive("i18n",["$sce","locale","localeEvents","localeConf",function(b,c,d,e){function f(a,c){c!==a.html()&&a.html(b.getTrustedHtml(c))}function g(a,b,d){c.isToken(b)?c.ready(c.getPath(b)).then(function(){f(a,c.getString(b,d))}):f(a,b)}return function(b,c,f){var h;f.$observe("i18n",function(a,b){a&&a!=b&&g(c,a,h)}),a.forEach(f.$attr,function(a,b){e.observableAttrs.test(a)&&f.$observe(b,function(a,d){(a&&a!=d||!h||!h[b])&&(h=h||{},h[b]=f[b],g(c,f.i18n,h))})}),b.$on(d.resourceUpdates,function(){g(c,f.i18n,h)}),b.$on(d.localeChanges,function(){g(c,f.i18n,h)})}}]).directive("i18nAttr",["locale","localeEvents",function(a,b){return function(c,d,e){function f(b,d){var f,h=c.$eval(d),i=[];for(var j in h)f=h[j],a.isToken(f)&&-1==i.indexOf(a.getPath(f))&&i.push(a.getPath(f));a.ready(i).then(function(){var b="";for(var c in h)f=h[c],b=a.getString(f),g[c]!==b&&e.$set(c,g[c]=b)})}var g={};e.$observe("i18nAttr",function(a,b){a&&a!=b&&f(d,a)}),c.$on(b.resourceUpdates,function(){f(d,e.i18nAttr)}),c.$on(b.localeChanges,function(){f(d,e.i18nAttr)})}}]),a.module("ngLocalize.InstalledLanguages",[]).value("localeSupported",{"en-US":"English (United States)"}).value("localeFallbacks",{en:"en-US"}),a.module("ngLocalize.Version",[]).constant("localeVer","1.2.0")}(window.angular,window,document); +!function(a){"use strict";a.module("ngLocalize.Config",[]).value("localeConf",{basePath:"languages",defaultLocale:"en-US",sharedDictionary:"common",fileExtension:".lang.json",persistSelection:!0,cookieName:"COOKIE_LOCALE_LANG",observableAttrs:new RegExp("^data-(?!ng-|i18n)"),delimiter:"::"}),a.module("ngLocalize.Events",[]).constant("localeEvents",{resourceUpdates:"ngLocalizeResourcesUpdated",localeChanges:"ngLocalizeLocaleChanged"}),a.module("ngLocalize",["ngSanitize","ngLocalize.Config","ngLocalize.Events","ngLocalize.InstalledLanguages"]).service("locale",["$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks",function(b,c,d,e,f,g,h,i,j,k){function l(a){return a&&a.length&&B.test(a)}function m(a){var b=a?a.split("."):"",c="";return b.length>1&&(c=b.slice(0,-1).join(".")),c}function n(a){var b=a?a.split("."):[],c="";return b.length&&(c=b[b.length-1]),c}function o(a,b){var c,d=null,e=a?a.split("."):[];if(e.length>1)for(d=y[b],c=0;c1){for(d=0;d1)c.forEach(function(a){for(var b=0;b")}function t(a,b){for(var c=0;ct$bq(V}%9ZCOvUh$SJ?+455qmHh6b##wky?UX&(q!zfBAJe&#F0_>Q|4h3 zYo@8KPsK0dguZ?`IsND8^JQj^$9|XxD_c0pV(cbauuPN1G9Mpf z2~wiINS2Rj=m)uGIIQ5TZM9D_SVh_!FbHYSRp_WVQ>OOkyU!SpU-Z0H><|+}vW>pV zl$Pab=;ZoDibdkCB4y~Ye^p9T;v$K?(AW8N#>84iE36ipC|c0@#+I4-DD%M7Bhpm* zD$}{EJh_VUf{8M96_0Ljbe;t=RqmUxkS^0lQ^!#kNvv}(jMU{r4n?tI>VjB_c}7c1 zm1bd<->66xbY|~_J4tdEst&5O01dn&NV;;yf!&;UsaE z%Q&yCQLk-Ml_jgxQMXG7QkmId@TpqL$~9N#l_dilcYo_uXTg0=A!vfpjf}&*7#(xl zG5x!9@8}p&q};2?Zg4>SE={m?vReP%-YbyyItiPiIGYmz<~daCAD`82)NrlGsZBCZCeCZsu%9@?A=_Yk&z-8NGn=tZ$#!C=O5W{UtD4_cin^^b z%T^he`$vp7FJ<0YfvB^>P#^02H2ll z)rj8>En-N6$y|Jo66uDqPurV;h5UeRf!NC_+!4OYjXOYl_Tyn4H*9k)dvIm zE!Lv7GF-M}LZvC>HcGLLs;2a5H}T(;fjQION*vGC@%bpf zG^rYj(vsV4P^8?q;7Rxz>H-P%`u*+4?-UY=p+E=KC3%MaS*}2eSE)hp9}Idx8cRCh#%zU2XaHyUT+Z7={6lWisRLA72M)v;N_**>ox&GQt zf73h0$xCHwTbJ3ev2~FPOT(>bBdkq94YyN9>{%{rl3?us5yoEfTui=Kk6N7MaP2BC zLJ|kiU%q^Q`StsU>(AfcUf+Ir^YW$Ms<$f3TB$@?+d`{%`XmS_!UluUX%Df0!m1vw zJtGiJ(?UtfZ^ERzz-`N)o=_Qprx1DnK}%)$Q&brSNfB7{URa;fuH|0aROx{jM7v{= zO#rI|y1Mv)E~<(4qLg?RB~h-X-mGSo88iYecLmlJ&kP&q z!f0Wzs{Zv*4DO~)P8jJ72b|5$p3a$MiB2ENYjS&bhVV9VHWy3}b}^)^!?}XevL0dQ zM^q%IS0Hodf<=zCqL)ETYJ6r^xL=lZ{NgdHpFi^ z$m;REVTxDmtdDk^Oi@E25QiQ9U{KUuL+_XB+@R@HI)VHgV4yO7u)_G-I6pftmbzzP zrY~Z-4tq+-&=(@yjCrQ&o6VXg ztM7aIE|F{IyB)e{bRY;qL#JB?wa|4l-7OuJ6}o+H+sTTCV=-Saby3N%6~(pT+s_=; zG|$hq*<}lU*iUzQXv99r211c6f_xDfj5_J!t1$cLbd{k*{+lND(BT)!6KTv5mE9kGtS&=F^Msc>+k6y;UWtX;VRgP@s5b zLkDP-4-leyJmck%yNR<}0N`x$w-@8_-?h>sf6C<&K)C&MWgUBL6N?aka`_h!`ryOk G6953Jrftap literal 2089 zcmV+^2-f!>iwFP!000001BF;?Z`;Zd{T`tIfnsHX8?9E>Z3`6CDtzRm~(!!!x1D38yvQQA&_`0tQ?HDbsVBiztxbs!Y2rtL&L>kQ9%Wo&wz5Rggw9uv%+)tpgq9wY zr7}>t&OPPJGA=41%Fmrn%@#f+s35+!Ci zO)XTGM|p9hVpZ+4I_KO?(}zfXm2=4caDDyd^X2{3^@ocq{JZ%2yUtT5SJ|U6WE$7(eNX%SV+IdF=`} zP4Yq}#m*bMxmBj}w9H&}yMQ8gqTzb`-@ZK^AmSA)vlc=ah zr^0s1{`R}ibc{Gw-c=JloQ~WF-0TiVin>uULj=+c`@4i#`u~%D;*|7svotMk+;l;P zbeB=$rAs`uv2x_9?eL~tEYhrU$M(%9801Lz0c#qpI^5+RSKQ|T4|&9A{DG}@vsz48 z&Qwumi6#w0idZE<5gNvYKnx1ZZkn}oTKgz7&9UWJihL1Ah@#M$rR&_ab$zrI5d+pp8T_?k{D*?7h9B}~SPZMuy81!4s#gEGL*oFy}WzgFg z#a3$jN}sgp{-#dHsrE_Yc%D|I8fmsPy*I1K>(HDHW1D^Kezq{QgP*kJdL33Y`w0>O zF4@xsNc8&4?YDa!*hz6}m@O$P^w0JLNL^(n0Ph$^$7!^UX}URygcb5hrwGO^GXjj!Wr= zX1jFyVo~OyN$y1`xq^qlTc*#LrR<-ulDAHs6M@y|_G|}>&v&74fvx@7T!!S@X><4V zCpo<4K}Dt(u_R_b(|e}V8=^7*0qu#^cA}?mbWCoT^|r)bPrcggY&Y^_bXd%f z=suhq+$Dp6>%ThLZ+eT7ibN{RAR*(LaSDLPEUZ4mGE5cy6lo(Zl53Nxdwz)Y&PiVP#2K`rcNC% zwR5}1uFYs$FSL8EeODzKiPif`s0WtCQqX=Qx0}1FY2@B&`RaD?xVLNdb0`X=8|Xr+ zhQ&NK8Fh8lQ|0y_S($^r|3NPffDsU}aSwaN)^C&%Ze1D7svjU1Qa%Y3hooJ6E3F6T z^oZImzaq=c3HNZn&cJX4OxL%L#utZ7OI;}l%P<0vu;d}DditiWh_1v<HrS%Si{j zT3ZgY{Ot{=fJ29CgYpP9hh8}j!)xqR@u#r(JhWZWRk*jJ-vYs+S*Avh=4RCFh0M3Z z$*g9;8ZADf+G5*LQ(I&M8q{{fi0Zn3@D>DI11x%ts`@&B)_Q0YIV6pmggLcKN@3dn3J%-mq?xk)y2Ts}OPwxhUKWnvP|B#CX;(7c1%0Bh| TM$9Ap$;E#G;uHB6HWB~;-*-F< diff --git a/dist/angular-localization.min.map b/dist/angular-localization.min.map index 07ed7b0..98d3107 100644 --- a/dist/angular-localization.min.map +++ b/dist/angular-localization.min.map @@ -1 +1 @@ -{"version":3,"file":"angular-localization.min.js","sources":["angular-localization.js"],"names":["angular","module","value","basePath","defaultLocale","sharedDictionary","fileExtension","persistSelection","cookieName","observableAttrs","RegExp","delimiter","constant","resourceUpdates","localeChanges","service","$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks","isToken","str","length","TOKEN_REGEX","test","getPath","tok","path","split","result","slice","join","getKey","getBundle","i","bundles","loadBundle","token","root","url","currentLocale","_loading","get","success","data","key","hasOwnProperty","$broadcast","deferrences","resolve","error","bundleReady","bundle","langFile","defer","promise","ready","paths","deferred","outstanding","isString","isArray","Error","forEach","push","all","applySubstitutions","text","subs","res","firstOfKind","sub","replace","v","k","getLocalizedString","txt","A","isValidToken","indexOf","fromJson","isObject","info","setLocale","lang","trim","isUndefined","cookieStore","put","getLocale","has","navigator","userLanguage","language","getString","filter","locale","input","args","directive","$sce","setText","elm","tag","html","getTrustedHtml","update","string","optArgs","then","scope","attrs","hasObservers","$observe","newVal","oldVal","$attr","attr","normAttr","i18n","$on","elem","updateText","target","attributes","exp","values","$eval","langFiles","lastValues","$set","i18nAttr","en-US","en","window","document"],"mappings":"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","sourceRoot":"/Users/chris/Development/angular-localization"} \ No newline at end of file +{"version":3,"file":"angular-localization.min.js","sources":["angular-localization.js"],"names":["angular","module","value","basePath","defaultLocale","sharedDictionary","fileExtension","persistSelection","cookieName","observableAttrs","RegExp","delimiter","constant","resourceUpdates","localeChanges","service","$injector","$http","$q","$log","$rootScope","$window","localeConf","localeEvents","localeSupported","localeFallbacks","isToken","str","length","TOKEN_REGEX","test","getPath","tok","path","split","result","slice","join","getKey","getBundle","lang","i","languageBundles","loadBundle","token","root","url","_loading","get","success","data","key","hasOwnProperty","$broadcast","deferrences","resolve","error","bundleReady","locale","bundle","langFile","defer","promise","ready","paths","deferred","outstanding","isString","isArray","Error","forEach","locales","push","all","applySubstitutions","text","subs","res","firstOfKind","sub","replace","v","k","getLocalizedString","txt","getStringForLocale","info","A","isValidToken","indexOf","fromJson","isObject","setLocale","fall","trim","currentLocale","cookieStore","put","getLocale","has","navigator","userLanguage","language","getString","filter","input","args","directive","$sce","setText","elm","tag","html","getTrustedHtml","update","string","optArgs","then","scope","attrs","hasObservers","$observe","newVal","oldVal","$attr","attr","normAttr","i18n","$on","elem","updateText","target","attributes","exp","values","$eval","langFiles","lastValues","$set","i18nAttr","en-US","aa-XX","aa-YY","en","aa","window","document"],"mappings":"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","sourceRoot":"/Users/chris/Development/angular-localization"} \ No newline at end of file diff --git a/src/localization.js b/src/localization.js index de3f43a..a78a7ee 100644 --- a/src/localization.js +++ b/src/localization.js @@ -3,6 +3,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve function ($injector, $http, $q, $log, $rootScope, $window, localeConf, localeEvents, localeSupported, localeFallbacks) { var TOKEN_REGEX = new RegExp('^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$'), currentLocale, + locales = [], languageBundles, deferrences, bundles, @@ -111,14 +112,14 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve } } - function bundleReady(path) { + function bundleReady(path, locale) { var bundle, token; path = path || localeConf.langFile; token = path + "._LOOKUP_"; - bundle = getBundle(token, currentLocale); + bundle = getBundle(token, locale); if (!deferrences[path]) { deferrences[path] = $q.defer(); @@ -128,7 +129,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve deferrences[path].resolve(path); } else { if (!bundle) { - loadBundle(token, currentLocale); + loadBundle(token, locale); } } @@ -148,16 +149,22 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve throw new Error("locale.ready requires either an Array or comma-separated list."); } + outstanding = []; if (paths.length > 1) { - outstanding = []; paths.forEach(function (path) { - outstanding.push(bundleReady(path)); + // Load all bundles that may be required by the fallback hierarchy + for (var i = 0; i < locales.length; i++) { + outstanding.push(bundleReady(path, locales[i])); + } }); - deferred = $q.all(outstanding); } else { - deferred = bundleReady(path); + // Load all bundles that may be required by the fallback hierarchy + for (var i = 0; i < locales.length; i++) { + outstanding.push(bundleReady(path, locales[i])); + } } + deferred = $q.all(outstanding); return deferred; } @@ -187,65 +194,89 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return res; } - function getLocalizedString(txt, subs, locale) { - var result = '', - bundle, + function getLocalizedString(txt, subs) { + var bundle, key, A, isValidToken = false; - var useLocale = currentLocale; - if (locale != null) { - useLocale = locale; + for (var i = 0; i < locales.length; i++) { + var result = getStringForLocale(txt, subs, locales[i]); + if(result != null) { + return result; + } } + $log.info("[localizationService] Key not found: " + txt); + return "%%KEY_NOT_FOUND%%"; + } + + function getStringForLocale(txt, subs, locale) { + var result = null, + bundle, + key, + A, + isValidToken = false; + if (angular.isString(txt) && !subs && txt.indexOf(localeConf.delimiter) != -1) { A = txt.split(localeConf.delimiter); txt = A[0]; subs = angular.fromJson(A[1]); } + // If the token isn't valid, then just return it isValidToken = isToken(txt); - if (isValidToken) { - if (!angular.isObject(subs)) { - subs = [subs]; - } + if (!isValidToken) { + return txt; + } - bundle = getBundle(txt, useLocale); - if (bundle && !bundle._loading) { - key = getKey(txt); + if (!angular.isObject(subs)) { + subs = [subs]; + } - if (bundle[key]) { - result = applySubstitutions(bundle[key], subs); - } else { - if (currentLocale != localeConf.defaultLocale && useLocale != localeConf.defaultLocale) { - result = getLocalizedString(txt, subs, localeConf.defaultLocale); - } else { - $log.info("[localizationService] Key not found: " + txt); - result = "%%KEY_NOT_FOUND%%"; - } - } - } else { - if (!bundle) { - loadBundle(txt, useLocale); - } + // Load the file + bundle = getBundle(txt, locale); + if (bundle && !bundle._loading) { + key = getKey(txt); + + if (bundle[key]) { + return applySubstitutions(bundle[key], subs); } } else { - result = txt; + if (!bundle) { + loadBundle(txt, locale); + } } - return result; + return null; } function setLocale(value) { var lang; + var fall; + if(!angular.isString(value)) { lang = localeConf.defaultLocale; } else { value = value.trim(); - lang = localeSupported[value] ? value : - localeFallbacks[value.split('-')[0]] || localeConf.defaultLocale; + + // Get the fallback first - if it's not valid, then use the default + if(localeSupported[localeFallbacks[value.split('-')[0]]] != null) { + fall = localeFallbacks[value.split('-')[0]]; + } + else { + fall = localeConf.defaultLocale; + } + + // Check if the requested locale is supported - if not, use the fallback + if(localeSupported[value] != null) { + lang = value; + } + else { + lang = fall; + fall = localeConf.defaultLocale; + } } if (languageBundles == null) { @@ -259,6 +290,16 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve deferrences = {}; currentLocale = lang; + // Create the locales list. + locales = []; + if(lang != localeConf.defaultLocale) { + locales.push(lang); + } + if(fall != localeConf.defaultLocale) { + locales.push(fall); + } + locales.push(localeConf.defaultLocale); + $rootScope.$broadcast(localeEvents.localeChanges, currentLocale); $rootScope.$broadcast(localeEvents.resourceUpdates); diff --git a/tests/unit/directiveSpec.js b/tests/unit/directiveSpec.js index 1f77d6e..34d9cd5 100644 --- a/tests/unit/directiveSpec.js +++ b/tests/unit/directiveSpec.js @@ -14,7 +14,19 @@ describe('directives', function () { helloWorld: 'Hello World', fullName: 'My name is {firstName} {lastName}', htmlToken: 'Hello World!', - 'key with spaces': 'some string value' + 'key with spaces': 'some string value', + fallback1: 'Fallback Default', + fallback2: 'Fallback Default', + fallback3: 'Fallback Default' + }); + + _httpBackend.whenGET('languages/aa-XX/common.lang.json').respond({ + fallback1: 'Fallback XX', + fallback2: 'Fallback XX' + }); + + _httpBackend.whenGET('languages/aa-YY/common.lang.json').respond({ + fallback1: 'Fallback YY' }); // force our service to pull down the required resource file @@ -29,6 +41,19 @@ describe('directives', function () { }); describe('i18n', function () { + it('should fallback correctly', inject(function ($compile, $rootScope, locale) { + locale.setLocale('aa-YY'); + var element = $compile('')($rootScope); + $rootScope.$digest(); + expect(element.text()).toEqual('Fallback YY'); + +// expect(locale.getString('common.fallback1')).toBe('Fallback YY'); +// locale.setLocale('aa-YY'); + // expect(locale.getString('common.fallback2')).toBe('Fallback XX'); + // locale.setLocale('aa-YY'); + // expect(locale.getString('common.fallback3')).toBe('Fallback Default'); + })); + it('should attach the localized version of a string', inject(function ($compile, $rootScope) { var element = $compile('')($rootScope); $rootScope.$digest(); @@ -88,5 +113,6 @@ describe('directives', function () { $rootScope.$digest(); expect(element.attr('placeholder')).toEqual('some string value'); })); + }); }); \ No newline at end of file From 9a6709b92dbbeb26d9d7f4bc1ff6b1763c5e9b13 Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Sun, 3 May 2015 10:15:40 +0100 Subject: [PATCH 4/7] Resolve merge formatting errors --- src/localization.js | 245 ++++++++++++++++++++++---------------------- 1 file changed, 122 insertions(+), 123 deletions(-) diff --git a/src/localization.js b/src/localization.js index 28c7f50..3b93ac6 100644 --- a/src/localization.js +++ b/src/localization.js @@ -1,13 +1,12 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Events', 'ngLocalize.InstalledLanguages']) - .service('locale', [$injector, $http, $q, $log, $rootScope, $window, localeConf, localeEvents, localeSupported, localeFallbacks, - function ($injector, $http, $q, $log, $rootScope, $window, localeConf, localeEvents, localeSupported, localeFallbacks) { - var TOKEN_REGEX = new RegExp('^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$'), - currentLocale, - locales = [], - languageBundles, - deferrences, - bundles, - cookieStore; + .service('locale', function ($injector, $http, $q, $log, $rootScope, $window, localeConf, localeEvents, localeSupported, localeFallbacks) { + var TOKEN_REGEX = new RegExp('^[\\w\\.-]+\\.[\\w\\s\\.-]+\\w(:.*)?$'), + currentLocale, + locales = [], + languageBundles, + deferrences, + bundles, + cookieStore; if (localeConf.persistSelection && $injector.has('$cookieStore')) { cookieStore = $injector.get('$cookieStore'); @@ -39,13 +38,13 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } - function getBundle(tok, lang) { - var result = null, - path = tok ? tok.split('.') : [], - i; + function getBundle(tok, lang) { + var result = null, + path = tok ? tok.split('.') : [], + i; - if (path.length > 1) { - result = languageBundles[lang]; + if (path.length > 1) { + result = languageBundles[lang]; for (i = 0; i < path.length - 1; i++) { if (result[path[i]]) { @@ -60,11 +59,11 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } - function loadBundle(token, lang) { - var path = token ? token.split('.') : '', - root = languageBundles[lang], - url = localeConf.basePath + '/' + lang, - i; + function loadBundle(token, lang) { + var path = token ? token.split('.') : '', + root = languageBundles[lang], + url = localeConf.basePath + '/' + lang, + i; if (path.length > 1) { for (i = 0; i < path.length - 1; i++) { @@ -112,9 +111,9 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve } } - function bundleReady(path, locale) { - var bundle, - token; + function bundleReady(path, locale) { + var bundle, + token; path = path || localeConf.langFile; token = path + "._LOOKUP_"; @@ -125,13 +124,13 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve deferrences[path] = $q.defer(); } - if (bundle && !bundle._loading) { - deferrences[path].resolve(path); - } else { - if (!bundle) { - loadBundle(token, locale); - } + if (bundle && !bundle._loading) { + deferrences[path].resolve(path); + } else { + if (!bundle) { + loadBundle(token, locale); } + } return deferrences[path].promise; } @@ -149,25 +148,25 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve throw new Error("locale.ready requires either an Array or comma-separated list."); } - outstanding = []; - if (paths.length > 1) { - paths.forEach(function (path) { - // Load all bundles that may be required by the fallback hierarchy - for (var i = 0; i < locales.length; i++) { - outstanding.push(bundleReady(path, locales[i])); - } - }); - } else { + outstanding = []; + if (paths.length > 1) { + paths.forEach(function (path) { // Load all bundles that may be required by the fallback hierarchy for (var i = 0; i < locales.length; i++) { outstanding.push(bundleReady(path, locales[i])); } + }); + } else { + // Load all bundles that may be required by the fallback hierarchy + for (var i = 0; i < locales.length; i++) { + outstanding.push(bundleReady(path, locales[i])); } - - deferred = $q.all(outstanding); - return deferred; } + deferred = $q.all(outstanding); + return deferred; + } + function applySubstitutions(text, subs) { var res = text, firstOfKind = 0; @@ -194,29 +193,29 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return res; } - function getLocalizedString(txt, subs) { - var bundle, - key, - A, - isValidToken = false; + function getLocalizedString(txt, subs) { + var bundle, + key, + A, + isValidToken = false; - for (var i = 0; i < locales.length; i++) { - var result = getStringForLocale(txt, subs, locales[i]); - if(result != null) { - return result; - } + for (var i = 0; i < locales.length; i++) { + var result = getStringForLocale(txt, subs, locales[i]); + if(result != null) { + return result; } - - $log.info("[localizationService] Key not found: " + txt); - return "%%KEY_NOT_FOUND%%"; } - function getStringForLocale(txt, subs, locale) { - var result = null, - bundle, - key, - A, - isValidToken = false; + $log.info("[localizationService] Key not found: " + txt); + return "%%KEY_NOT_FOUND%%"; + } + + function getStringForLocale(txt, subs, locale) { + var result = null, + bundle, + key, + A, + isValidToken = false; if (angular.isString(txt) && !subs && txt.indexOf(localeConf.delimiter) != -1) { A = txt.split(localeConf.delimiter); @@ -224,84 +223,84 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve subs = angular.fromJson(A[1]); } - // If the token isn't valid, then just return it - isValidToken = isToken(txt); - if (!isValidToken) { - return txt; - } + // If the token isn't valid, then just return it + isValidToken = isToken(txt); + if (!isValidToken) { + return txt; + } - if (!angular.isObject(subs)) { - subs = [subs]; - } + if (!angular.isObject(subs)) { + subs = [subs]; + } - // Load the file - bundle = getBundle(txt, locale); - if (bundle && !bundle._loading) { - key = getKey(txt); + // Load the file + bundle = getBundle(txt, locale); + if (bundle && !bundle._loading) { + key = getKey(txt); - if (bundle[key]) { - return applySubstitutions(bundle[key], subs); - } - } else { - if (!bundle) { - loadBundle(txt, locale); - } + if (bundle[key]) { + return applySubstitutions(bundle[key], subs); + } + } else { + if (!bundle) { + loadBundle(txt, locale); } - - return null; } - function setLocale(value) { - var lang; - var fall; + return null; + } - if(!angular.isString(value)) { - lang = localeConf.defaultLocale; - } - else { - value = value.trim(); + function setLocale(value) { + var lang; + var fall; - // Get the fallback first - if it's not valid, then use the default - if(localeSupported[localeFallbacks[value.split('-')[0]]] != null) { - fall = localeFallbacks[value.split('-')[0]]; - } - else { - fall = localeConf.defaultLocale; - } + if(!angular.isString(value)) { + lang = localeConf.defaultLocale; + } + else { + value = value.trim(); - // Check if the requested locale is supported - if not, use the fallback - if(localeSupported[value] != null) { - lang = value; - } - else { - lang = fall; - fall = localeConf.defaultLocale; - } + // Get the fallback first - if it's not valid, then use the default + if(localeSupported[localeFallbacks[value.split('-')[0]]] != null) { + fall = localeFallbacks[value.split('-')[0]]; + } + else { + fall = localeConf.defaultLocale; } - if (languageBundles == null) { - languageBundles = {}; - angular.forEach(localeSupported, function(value, key) { - languageBundles[key] = {}; - }); + // Check if the requested locale is supported - if not, use the fallback + if(localeSupported[value] != null) { + lang = value; + } + else { + lang = fall; + fall = localeConf.defaultLocale; } + } + + if (languageBundles == null) { + languageBundles = {}; + angular.forEach(localeSupported, function(value, key) { + languageBundles[key] = {}; + }); + } - if (lang != currentLocale) { - deferrences = {}; - currentLocale = lang; + if (lang != currentLocale) { + deferrences = {}; + currentLocale = lang; - // Create the locales list. - locales = []; - if(lang != localeConf.defaultLocale) { - locales.push(lang); - } - if(fall != localeConf.defaultLocale) { - locales.push(fall); - } - locales.push(localeConf.defaultLocale); + // Create the locales list. + locales = []; + if(lang != localeConf.defaultLocale) { + locales.push(lang); + } + if(fall != localeConf.defaultLocale) { + locales.push(fall); + } + locales.push(localeConf.defaultLocale); - $rootScope.$broadcast(localeEvents.localeChanges, currentLocale); - $rootScope.$broadcast(localeEvents.resourceUpdates); + $rootScope.$broadcast(localeEvents.localeChanges, currentLocale); + $rootScope.$broadcast(localeEvents.resourceUpdates); if (cookieStore) { cookieStore.put(localeConf.cookieName, lang); From beb9ba1402390cdcde1622ec26e00cc046aef4d1 Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Sun, 3 May 2015 13:18:27 +0100 Subject: [PATCH 5/7] Fixed bug loading files. The path into deference object needs to include the locale to ensure all promises are resolved. --- src/localization.js | 80 ++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/src/localization.js b/src/localization.js index 3b93ac6..130e0ab 100644 --- a/src/localization.js +++ b/src/localization.js @@ -4,7 +4,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve currentLocale, locales = [], languageBundles, - deferrences, + deferrences = {}, bundles, cookieStore; @@ -38,6 +38,13 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } + /** + * Return the bundle for the requested token and language + * @param tok The requested token. The token is split between paths using the point + * @param lang The requested language + * @returns {*} The bundle object if the bundle has been loaded. + * If the bundle is not loaded, returns null + */ function getBundle(tok, lang) { var result = null, path = tok ? tok.split('.') : [], @@ -46,6 +53,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve if (path.length > 1) { result = languageBundles[lang]; + // Iterate through the bundle tree to find the requested bundle for (i = 0; i < path.length - 1; i++) { if (result[path[i]]) { result = result[path[i]]; @@ -59,13 +67,23 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve return result; } + /** + * Loads a language bundle from the server. + * @param token The token, including the path and string name (separated by a .) + * Mulitple folders can be separated by a '.' - the last token being the + * filename. + * @param lang The requested localization + */ function loadBundle(token, lang) { var path = token ? token.split('.') : '', root = languageBundles[lang], url = localeConf.basePath + '/' + lang, i; + // If the path is defined... if (path.length > 1) { + // Concatenate the path together to form the URL + // Build a tree object where the bundle information will be loaded for (i = 0; i < path.length - 1; i++) { if (!root[path[i]]) { root[path[i]] = {}; @@ -75,10 +93,12 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve } if (!root._loading) { + // Remember that we're loading this bundle to stop subsequent calls to the server root._loading = true; url += localeConf.fileExtension; + // Request the data from the server $http.get(url) .success(function (data) { var key, @@ -97,8 +117,9 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve $rootScope.$broadcast(localeEvents.resourceUpdates); // If we issued a Promise for this file, resolve it now. - if (deferrences[path]) { - deferrences[path].resolve(path); + var localpath = path + "." + lang; + if (deferrences[localpath]) { + deferrences[localpath].resolve(localpath); } }) .error(function (data) { @@ -111,6 +132,12 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve } } + /** + * Checks if a bundle has been loaded, and if not, loaded it + * @param path bundle path + * @param locale requested locale + * @returns promise. If the bundle is loaded, the promise is already resolved + */ function bundleReady(path, locale) { var bundle, token; @@ -118,21 +145,26 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve path = path || localeConf.langFile; token = path + "._LOOKUP_"; - bundle = getBundle(token, locale); + // Get the bundle if it's loaded. Returns null if not loaded + bundle = getBundle(token, locale); - if (!deferrences[path]) { - deferrences[path] = $q.defer(); + var localepath = path + "." + locale; + + // Create a promise for this bundle + if (!deferrences[localepath]) { + deferrences[localepath] = $q.defer(); } if (bundle && !bundle._loading) { - deferrences[path].resolve(path); - } else { - if (!bundle) { - loadBundle(token, locale); - } + // The bundle has been loaded, so full-fill our promise + deferrences[localepath].resolve(localepath); + } else if (!bundle) { + // The bundle is not loaded, so load it + loadBundle(token, locale); } - return deferrences[path].promise; + // Return the promise for the bundle we requested + return deferrences[localepath].promise; } function ready(path) { @@ -143,25 +175,18 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve if (angular.isString(path)) { paths = path.split(','); } else if (angular.isArray(path)) { - paths = path; + paths = [path]; } else { throw new Error("locale.ready requires either an Array or comma-separated list."); } outstanding = []; - if (paths.length > 1) { - paths.forEach(function (path) { - // Load all bundles that may be required by the fallback hierarchy - for (var i = 0; i < locales.length; i++) { - outstanding.push(bundleReady(path, locales[i])); - } - }); - } else { + paths.forEach(function (path) { // Load all bundles that may be required by the fallback hierarchy - for (var i = 0; i < locales.length; i++) { - outstanding.push(bundleReady(path, locales[i])); - } - } + locales.forEach(function(locale) { + outstanding.push(bundleReady(path, locale)); + }); + }); deferred = $q.all(outstanding); return deferred; @@ -285,8 +310,11 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve }); } + // If the language has changed, then we need to reset the state + // so we reload files next time if (lang != currentLocale) { - deferrences = {}; + // Note that we don't reset the deferrences array since the array + // path includes the language, we don't need to reload all locales currentLocale = lang; // Create the locales list. From 2fdd3b7fe1c782e851b9f581524465cc0aef771c Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Sun, 3 May 2015 13:18:55 +0100 Subject: [PATCH 6/7] Updated fallback tests and added new test cases --- tests/unit/directiveSpec.js | 64 +++++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 9 deletions(-) diff --git a/tests/unit/directiveSpec.js b/tests/unit/directiveSpec.js index 34d9cd5..fe6a95e 100644 --- a/tests/unit/directiveSpec.js +++ b/tests/unit/directiveSpec.js @@ -6,6 +6,22 @@ describe('directives', function () { beforeEach(function () { module('ngLocalize'); + var mockLocaleSupported = { + 'en-US': "English (United States)", + 'aa-XX': "English (XX)", + 'aa-YY': "English (YY)" + }; + + var mockLocaleFallbacks = { + 'en': 'en-US', + 'aa': 'aa-XX' + }; + + module(function ($provide) { + $provide.value('localeSupported', mockLocaleSupported); + $provide.value('localeFallbacks', mockLocaleFallbacks); + }); + inject(function ($injector) { // Set up the mock http service responses _httpBackend = $injector.get('$httpBackend'); @@ -21,6 +37,7 @@ describe('directives', function () { }); _httpBackend.whenGET('languages/aa-XX/common.lang.json').respond({ + helloWorld: 'Hello World XX', fallback1: 'Fallback XX', fallback2: 'Fallback XX' }); @@ -29,9 +46,9 @@ describe('directives', function () { fallback1: 'Fallback YY' }); - // force our service to pull down the required resource file - $injector.get('locale').ready('common'); - _httpBackend.flush(); + _httpBackend.whenGET('languages/en-US/deep-path/common.lang.json').respond({ + helloWorld: 'Hello World from the deep' + }); }); }); @@ -41,21 +58,46 @@ describe('directives', function () { }); describe('i18n', function () { + it('should attach the localized version of a string with multiple path', inject(function ($compile, $rootScope) { + var element = $compile('')($rootScope); + _httpBackend.flush(); + $rootScope.$digest(); + expect(element.text()).toEqual('Hello World from the deep'); + })); + + it('should reload the localisations when local changes', inject(function ($compile, $rootScope, locale) { + var element = $compile('')($rootScope); + _httpBackend.flush(); + $rootScope.$digest(); + expect(element.text()).toEqual('Hello World'); + + locale.setLocale('aa-XX'); + element = $compile('')($rootScope); + _httpBackend.flush(); + $rootScope.$digest(); + expect(element.text()).toEqual('Hello World XX'); + })); + it('should fallback correctly', inject(function ($compile, $rootScope, locale) { locale.setLocale('aa-YY'); + expect(locale.getLocale()).toEqual("aa-YY"); var element = $compile('')($rootScope); + _httpBackend.flush(); $rootScope.$digest(); expect(element.text()).toEqual('Fallback YY'); -// expect(locale.getString('common.fallback1')).toBe('Fallback YY'); -// locale.setLocale('aa-YY'); - // expect(locale.getString('common.fallback2')).toBe('Fallback XX'); - // locale.setLocale('aa-YY'); - // expect(locale.getString('common.fallback3')).toBe('Fallback Default'); + element = $compile('')($rootScope); + $rootScope.$digest(); + expect(element.text()).toEqual('Fallback XX'); + + element = $compile('')($rootScope); + $rootScope.$digest(); + expect(element.text()).toEqual('Fallback Default'); })); it('should attach the localized version of a string', inject(function ($compile, $rootScope) { var element = $compile('')($rootScope); + _httpBackend.flush(); $rootScope.$digest(); expect(element.text()).toEqual('Hello World'); })); @@ -65,6 +107,7 @@ describe('directives', function () { '

' ); $compile(element)($rootScope); + _httpBackend.flush(); $rootScope.$digest(); expect(element.text()).toEqual('My name is Rahul Doshi'); })); @@ -83,6 +126,7 @@ describe('directives', function () { '

' ); $compile(element)($rootScope); + _httpBackend.flush(); $rootScope.$digest(); expect(element.children().prop('tagName').toLowerCase()).toEqual('b'); expect(element.text()).toEqual('Hello World!'); @@ -90,6 +134,7 @@ describe('directives', function () { it('should pass through tokens that contain whitespace', inject(function ($compile, $rootScope) { var element = $compile('')($rootScope); + _httpBackend.flush(); $rootScope.$digest(); expect(element.text()).toEqual('some string value'); })); @@ -101,6 +146,7 @@ describe('directives', function () { '' ); $compile(element)($rootScope); + _httpBackend.flush(); $rootScope.$digest(); expect(element.attr('placeholder')).toEqual('Hello World'); })); @@ -110,9 +156,9 @@ describe('directives', function () { '' ); $compile(element)($rootScope); + _httpBackend.flush(); $rootScope.$digest(); expect(element.attr('placeholder')).toEqual('some string value'); })); - }); }); \ No newline at end of file From 8d40c285cfcc16b71198182d74628da9009cd7f5 Mon Sep 17 00:00:00 2001 From: Chris Jackson Date: Mon, 4 May 2015 12:02:16 +0100 Subject: [PATCH 7/7] Fix bug with multiple paths in ready. Add test case! --- src/localization.js | 2 +- tests/unit/serviceSpec.js | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/localization.js b/src/localization.js index 130e0ab..374aa52 100644 --- a/src/localization.js +++ b/src/localization.js @@ -175,7 +175,7 @@ angular.module('ngLocalize', ['ngSanitize', 'ngLocalize.Config', 'ngLocalize.Eve if (angular.isString(path)) { paths = path.split(','); } else if (angular.isArray(path)) { - paths = [path]; + paths = path; } else { throw new Error("locale.ready requires either an Array or comma-separated list."); } diff --git a/tests/unit/serviceSpec.js b/tests/unit/serviceSpec.js index 85ab953..0f61358 100644 --- a/tests/unit/serviceSpec.js +++ b/tests/unit/serviceSpec.js @@ -13,6 +13,13 @@ describe('service', function () { expect(locale.getLocale()).toBe('en-US'); })); + it('should correctly handle multiple paths in ready', inject(function (locale, $httpBackend) { + $httpBackend.expectGET('languages/en-US/common1.lang.json').respond(); + $httpBackend.expectGET('languages/en-US/common2.lang.json').respond(); + locale.ready(['common1', 'common2']); + $httpBackend.flush(); + })); + it('should go after the correct file', inject(function (locale, $httpBackend) { $httpBackend.expectGET('languages/en-US/common.lang.json').respond(); locale.ready('common');