1if(typeof(ss) == 'undefined') ss = {}; 2 3/* 4 * Lightweight clientside i18n implementation. 5 * Caution: Only available after DOM loaded because we need to detect the language 6 * 7 * For non-i18n stub implementation, see framework/javascript/i18nx.js 8 * 9 * Based on jQuery i18n plugin: 1.0.0 Feb-10-2008 10 * 11 * Dual licensed under the MIT and GPL licenses: 12 * http://www.opensource.org/licenses/mit-license.php 13 * http://www.gnu.org/licenses/gpl.html 14 * 15 * Based on 'javascript i18n that almost doesn't suck' by markos 16 * http://markos.gaivo.net/blog/?p=100 17 */ 18ss.i18n = { 19 20 currentLocale: null, 21 22 defaultLocale: 'en_US', 23 24 lang: {}, 25 26 inited: false, 27 28 init: function() { 29 if(this.inited) return; 30 31 this.currentLocale = this.detectLocale(); 32 this.inited = true; 33 }, 34 35 /** 36 * set_locale() 37 * Set locale in long format, e.g. "de_AT" for Austrian German. 38 * @param string locale 39 */ 40 setLocale: function(locale) { 41 this.currentLocale = locale; 42 }, 43 44 /** 45 * getLocale() 46 * Get locale in long format. Falls back to i18n.defaut_locale. 47 * @return string 48 */ 49 getLocale: function() { 50 return (this.currentLocale) ? this.currentLocale : this.defaultLocale; 51 }, 52 53 /** 54 * _() 55 * The actual translation function. Looks the given string up in the 56 * dictionary and returns the translation if one exists. If a translation 57 * is not found, returns the original word 58 * 59 * @param string entity A "long" locale format, e.g. "de_DE" (Required) 60 * @param string fallbackString (Required) 61 * @param int priority (not used) 62 * @param string context Give translators context for the string 63 * @return string : Translated word 64 * 65 */ 66 _t: function (entity, fallbackString, priority, context) { 67 this.init(); 68 69 var langName = this.getLocale().replace(/_[\w]+/i, ''); 70 var defaultlangName = this.defaultLocale.replace(/_[\w]+/i, ''); 71 72 if (this.lang && this.lang[this.getLocale()] && this.lang[this.getLocale()][entity]) { 73 return this.lang[this.getLocale()][entity]; 74 } else if (this.lang && this.lang[langName] && this.lang[langName][entity]) { 75 return this.lang[langName][entity]; 76 } else if (this.lang && this.lang[this.defaultLocale] && this.lang[this.defaultLocale][entity]) { 77 return this.lang[this.defaultLocale][entity]; 78 } else if (this.lang && this.lang[defaultlangName] && this.lang[defaultlangName][entity]) { 79 return this.lang[defaultlangName][entity]; 80 } else if(fallbackString) { 81 return fallbackString; 82 } else { 83 return ''; 84 } 85 }, 86 87 /** 88 * Add entities to a dictionary. If a dictionary doesn't 89 * exist for this locale, its automatically created. 90 * Existing entities are overwritten. 91 * 92 * @param string locale 93 * @param Object dict 94 */ 95 addDictionary: function(locale, dict) { 96 if(!this.lang[locale]) this.lang[locale] = {}; 97 for(entity in dict) { 98 this.lang[locale][entity] = dict[entity]; 99 } 100 }, 101 102 /** 103 * Get dictionary for a specific locale. 104 * 105 * @param string locale 106 */ 107 getDictionary: function(locale) { 108 return this.lang[locale]; 109 }, 110 111 /** 112 * stripStr() 113 * 114 * @param string str : The string to strip 115 * @return string result : Stripped string 116 * 117 */ 118 stripStr: function(str) { 119 return str.replace(/^\s*/, "").replace(/\s*$/, ""); 120 }, 121 122 /** 123 * stripStrML() 124 * 125 * @param string str : The multi-line string to strip 126 * @return string result : Stripped string 127 * 128 */ 129 stripStrML: function(str) { 130 // Split because m flag doesn't exist before JS1.5 and we need to 131 // strip newlines anyway 132 var parts = str.split('\n'); 133 for (var i=0; i<parts.length; i++) 134 parts[i] = stripStr(parts[i]); 135 136 // Don't join with empty strings, because it "concats" words 137 // And strip again 138 return stripStr(parts.join(" ")); 139 }, 140 141 /** 142 * Substitutes %s with parameters 143 * given in list. %%s is used to escape %s. 144 * 145 * @param string S : The string to perform the substitutions on. 146 * @return string The new string with substitutions made 147 */ 148 sprintf: function(S) { 149 if (arguments.length == 1) return S; 150 151 var args = [], 152 len = arguments.length, 153 index = 0, 154 regx = new RegExp('(.?)(%s)', 'g'), 155 result; 156 157 for (var i=1; i<len; ++i) { 158 args.push(arguments[i]); 159 }; 160 161 result = S.replace(regx, function(match, subMatch1, subMatch2, offset, string){ 162 if (subMatch1 == '%') return match;
162 // skip %%s 163 return subMatch1 + args[index++]; 164 }); 165 166 return result; 167 }, 168 169 /** 170 * Substitutes variables with a list of injections. 171 * 172 * @param string S : The string to perform the substitutions on. 173 * @param object map : An object with the substitions map e.g. {var: value} 174 * @return string The new string with substitutions made 175 */ 176 inject: function(S, map) { 177 var regx = new RegExp("\{([A-Za-z0-9_]*)\}", "g"), 178 result; 179 180 result = S.replace(regx, function(match, key, offset, string){ 181 return (map[key]) ? map[key] : match; 182 }); 183 184 return result; 185 }, 186 187 /** 188 * Detect document language settings by looking at <meta> tags. 189 * If no match is found, returns this.defaultLocale. 190 * 191 * @todo get by <html lang=''> - needs modification of SSViewer 192 * 193 * @return string Locale in mixed lowercase/uppercase format suitable 194 * for usage in ss.i18n.lang arrays (e.g. 'en_US'). 195 */ 196 detectLocale: function() { 197 var rawLocale; 198 var detectedLocale; 199 200 // get by container tag 201 rawLocale = jQuery('html').attr('lang') || jQuery('body').attr('lang'); 202 203 // get by meta 204 if(!rawLocale) { 205 var metas = document.getElementsByTagName('meta'); 206 for(var i=0; i<metas.length; i++) { 207 if(metas[i].attributes['http-equiv'] && metas[i].attributes['http-equiv'].nodeValue.toLowerCase() == 'content-language') { 208 rawLocale = metas[i].attributes['content'].nodeValue; 209 } 210 } 211 } 212 213 // fallback to default locale 214 if(!rawLocale) rawLocale = this.defaultLocale; 215 216 var rawLocaleParts = rawLocale.match(/([^-|_]*)[-|_](.*)/); 217 // get locale (e.g. 'en_US') from common name (e.g. 'en') 218 // by looking at ss.i18n.lang tables 219 if(rawLocale.length == 2) { 220 for(compareLocale in ss.i18n.lang) { 221 if(compareLocale.substr(0,2).toLowerCase() == rawLocale.toLowerCase()) { 222 detectedLocale = compareLocale; 223 break; 224 } 225 } 226 } else if(rawLocaleParts) { 227 detectedLocale = rawLocaleParts[1].toLowerCase() + '_' + rawLocaleParts[2].toUpperCase(); 228 } 229 230 return detectedLocale; 231 }, 232 233 /** 234 * Attach an event listener to the given object. 235 * Modeled after behaviour.js, but externalized 236 * to keep the i18n library standalone for now. 237 */ 238 addEvent: function(obj, evType, fn, useCapture){ 239 if (obj.addEventListener){ 240 obj.addEventListener(evType, fn, useCapture); 241 return true; 242 } else if (obj.attachEvent){ 243 var r = obj.attachEvent("on"+evType, fn); 244 return r; 245 } else { 246 alert("Handler could not be attached"); 247 } 248 } 249}; 250 251 252 253ss.i18n.addEvent(window, "load", function() { 254 ss.i18n.init(); 255});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.