1angular.module('gettext', []); 2 3angular.module('gettext').constant('gettext', function (str) { 4 /* 5 * Does nothing, simply returns the input string. 6 * 7 * This function serves as a marker for `grunt-angular-gettext` to know that 8 * this string should be extracted for translations. 9 */ 10 return str; 11}); 12 13angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", "$cacheFactory", "$interpolate", "$rootScope", function (gettextPlurals, $http, $cacheFactory, $interpolate, $rootScope) { 14 var catalog; 15 var noContext = '$$noContext'; 16 17 // IE8 returns UPPER CASE tags, even though the source is lower case. 18 // This can causes the (key) string in the DOM to have a different case to 19 // the string in the `po` files. 20 // IE9, IE10 and IE11 reorders the attributes of tags. 21 var test = '<span id="test" title="test" class="tested">test</span>'; 22 var isHTMLModified = (angular.element('<span>' + test + '</span>').html() !== test); 23 24 var prefixDebug = function (string) { 25 if (catalog.debug && catalog.currentLanguage !== catalog.baseLanguage) { 26 return catalog.debugPrefix + string; 27 } else { 28 return string; 29 } 30 }; 31 32 var addTranslatedMarkers = function (string) { 33 if (catalog.showTranslatedMarkers) { 34 return catalog.translatedMarkerPrefix + string + catalog.translatedMarkerSuffix; 35 } else { 36 return string; 37 } 38 }; 39 40 function broadcastUpdated() { 41 $rootScope.$broadcast('gettextLanguageChanged'); 42 } 43 44 catalog = { 45 debug: false, 46 debugPrefix: '[MISSING]: ', 47 showTranslatedMarkers: false, 48 translatedMarkerPrefix: '[', 49 translatedMarkerSuffix: ']', 50 strings: {}, 51 baseLanguage: 'en', 52 currentLanguage: 'en', 53 cache: $cacheFactory('strings'), 54 55 setCurrentLanguage: function (lang) { 56 this.currentLanguage = lang; 57 broadcastUpdated(); 58 }, 59 60 getCurrentLanguage: function () { 61 return this.currentLanguage; 62 }, 63 64 setStrings: function (language, strings) { 65 if (!this.strings[language]) { 66 this.strings[language] = {}; 67 } 68 69 for (var key in strings) { 70 var val = strings[key]; 71 72 if (isHTMLModified) { 73 // Use the DOM engine to render any HTML in the key (#131). 74 key = angular.element('<span>' + key + '</span>').html(); 75 } 76 77 if (angular.isString(val) || angular.isArray(val)) { 78 // No context, wrap it in $$noContext. 79 var obj = {}; 80 obj[noContext] = val; 81 val = obj; 82 } 83 84 // Expand single strings for each context. 85 for (var context in val) { 86 var str = val[context]; 87 val[context] = angular.isArray(str) ? str : [str]; 88 } 89 this.strings[language][key] = val; 90 } 91 92 broadcastUpdated(); 93 }, 94 95 getStringForm: function (string, n, context) { 96 var stringTable = this.strings[this.currentLanguage] || {}; 97 var contexts = stringTable[string] || {}; 98 var plurals = contexts[context || noContext] || []; 99 return plurals[n]; 100 }, 101 102 getString: function (string, scope, context) { 103 string = this.getStringForm(string, 0, context) || prefixDebug(string); 104 string = scope ? $interpolate(string)(scope) : string; 105 return addTranslatedMarkers(string); 106 }, 107 108 getPlural: function (n, string, stringPlural, scope, context) { 109 var form = gettextPlurals(this.currentLanguage, n); 110 string = this.getStringForm(string, form, context) || prefixDebug(n === 1 ? string : stringPlural); 111 if (scope) { 112 scope.$count = n;
vendor: 9,653 bytes, lines 113-352
113 string = $interpolate(string)(scope); 114 } 115 return addTranslatedMarkers(string); 116 }, 117 118 loadRemote: function (url) { 119 return $http({ 120 method: 'GET', 121 url: url, 122 cache: catalog.cache 123 }).success(function (data) { 124 for (var lang in data) { 125 catalog.setStrings(lang, data[lang]); 126 } 127 }); 128 } 129 }; 130 131 return catalog; 132}]); 133 134angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$animate", "$compile", "$window", function (gettextCatalog, $parse, $animate, $compile, $window) { 135 // Trim polyfill for old browsers (instead of jQuery) 136 // Based on AngularJS-v1.2.2 (angular.js#620) 137 var trim = (function () { 138 if (!String.prototype.trim) { 139 return function (value) { 140 return (typeof value === 'string') ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value; 141 }; 142 } 143 return function (value) { 144 return (typeof value === 'string') ? value.trim() : value; 145 }; 146 })(); 147 148 function assert(condition, missing, found) { 149 if (!condition) { 150 throw new Error('You should add a ' + missing + ' attribute whenever you add a ' + found + ' attribute.'); 151 } 152 } 153 154 var msie = parseInt((/msie (\d+)/.exec(angular.lowercase($window.navigator.userAgent)) || [])[1], 10); 155 156 return { 157 restrict: 'AE', 158 terminal: true, 159 compile: function compile(element, attrs) { 160 // Validate attributes 161 assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural'); 162 assert(!attrs.translateN || attrs.translatePlural, 'translate-plural', 'translate-n'); 163 164 var msgid = trim(element.html()); 165 var translatePlural = attrs.translatePlural; 166 var translateContext = attrs.translateContext; 167 168 if (msie <= 8) { 169 // Workaround fix relating to angular adding a comment node to 170 // anchors. angular/angular.js/#1949 / angular/angular.js/#2013 171 if (msgid.slice(-13) === '<!--IE fix-->') { 172 msgid = msgid.slice(0, -13); 173 } 174 } 175 176 return { 177 post: function (scope, element, attrs) { 178 var countFn = $parse(attrs.translateN); 179 var pluralScope = null; 180 var linking = true; 181 182 function update() { 183 // Fetch correct translated string. 184 var translated; 185 if (translatePlural) { 186 scope = pluralScope || (pluralScope = scope.$new()); 187 scope.$count = countFn(scope); 188 translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural, null, translateContext); 189 } else { 190 translated = gettextCatalog.getString(msgid, null, translateContext); 191 } 192 193 var oldContents = element.contents(); 194 195 if (oldContents.length === 0) { 196 return; 197 } 198 199 // Avoid redundant swaps 200 if (translated === trim(oldContents.html())) { 201 // Take care of unlinked content 202 if (linking) { 203 $compile(oldContents)(scope); 204 } 205 return; 206 } 207 208 // Swap in the translation 209 var newWrapper = angular.element('<span>' + translated + '</span>'); 210 $compile(newWrapper.contents())(scope); 211 var newContents = newWrapper.contents(); 212 213 $animate.enter(newContents, element); 214 $animate.leave(oldContents); 215 } 216 217 if (attrs.translateN) { 218 scope.$watch(attrs.translateN, update); 219 } 220 221 scope.$on('gettextLanguageChanged', update); 222 223 update(); 224 linking = false; 225 } 226 }; 227 } 228 }; 229}]); 230 231angular.module('gettext').filter('translate', ["gettextCatalog", function (gettextCatalog) { 232 function filter(input, context) { 233 return gettextCatalog.getString(input, null, context); 234 } 235 filter.$stateful = true; 236 return filter; 237}]); 238 239// Do not edit this file, it is autogenerated using genplurals.py! 240angular.module("gettext").factory("gettextPlurals", function () { 241 return function (langCode, n) { 242 switch (langCode) { 243 case "ay": // Aymará 244 case "bo": // Tibetan 245 case "cgg": // Chiga 246 case "dz": // Dzongkha 247 case "fa": // Persian 248 case "id": // Indonesian 249 case "ja": // Japanese 250 case "jbo": // Lojban 251 case "ka": // Georgian 252 case "kk": // Kazakh 253 case "km": // Khmer 254 case "ko": // Korean 255 case "ky": // Kyrgyz 256 case "lo": // Lao 257 case "ms": // Malay 258 case "my": // Burmese 259 case "sah": // Yakut 260 case "su": // Sundanese 261 case "th": // Thai 262 case "tt": // Tatar 263 case "ug": // Uyghur 264 case "vi": // Vietnamese 265 case "wo": // Wolof 266 case "zh": // Chinese 267 // 1 form 268 return 0; 269 case "is": // Icelandic 270 // 2 forms 271 return (n % 10 != 1 || n % 100 == 11) ? 1 : 0; 272 case "jv": // Javanese 273 // 2 forms 274 return n != 0 ? 1 : 0; 275 case "mk": // Macedonian 276 // 2 forms 277 return n == 1 || n % 10 == 1 ? 0 : 1; 278 case "ach": // Acholi 279 case "ak": // Akan 280 case "am": // Amharic 281 case "arn": // Mapudungun 282 case "br": // Breton 283 case "fil": // Filipino 284 case "fr": // French 285 case "gun": // Gun 286 case "ln": // Lingala 287 case "mfe": // Mauritian Creole 288 case "mg": // Malagasy 289 case "mi": // Maori 290 case "oc": // Occitan 291 case "pt_BR": // Brazilian Portuguese 292 case "tg": // Tajik 293 case "ti": // Tigrinya 294 case "tr": // Turkish 295 case "uz": // Uzbek 296 case "wa": // Walloon 297 case "zh": // Chinese 298 // 2 forms 299 return n > 1 ? 1 : 0; 300 case "lv": // Latvian 301 // 3 forms 302 return (n % 10 == 1 && n % 100 != 11 ? 0 : n != 0 ? 1 : 2); 303 case "lt": // Lithuanian 304 // 3 forms 305 return (n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); 306 case "be": // Belarusian 307 case "bs": // Bosnian 308 case "hr": // Croatian 309 case "ru": // Russian 310 case "sr": // Serbian 311 case "uk": // Ukrainian 312 // 3 forms 313 return (n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); 314 case "mnk": // Mandinka 315 // 3 forms 316 return (n == 0 ? 0 : n == 1 ? 1 : 2); 317 case "ro": // Romanian 318 // 3 forms 319 return (n == 1 ? 0 : (n == 0 || (n % 100 > 0 && n % 100 < 20)) ? 1 : 2); 320 case "pl": // Polish 321 // 3 forms 322 return (n == 1 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2); 323 case "cs": // Czech 324 case "sk": // Slovak 325 // 3 forms 326 return (n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2; 327 case "sl": // Slovenian 328 // 4 forms 329 return (n % 100 == 1 ? 1 : n % 100 == 2 ? 2 : n % 100 == 3 || n % 100 == 4 ? 3 : 0); 330 case "mt": // Maltese 331 // 4 forms 332 return (n == 1 ? 0 : n == 0 || (n % 100 > 1 && n % 100 < 11) ? 1 : (n % 100 > 10 && n % 100 < 20) ? 2 : 3); 333 case "gd": // Scottish Gaelic 334 // 4 forms 335 return (n == 1 || n == 11) ? 0 : (n == 2 || n == 12) ? 1 : (n > 2 && n < 20) ? 2 : 3; 336 case "cy": // Welsh 337 // 4 forms 338 return (n == 1) ? 0 : (n == 2) ? 1 : (n != 8 && n != 11) ? 2 : 3; 339 case "kw": // Cornish 340 // 4 forms 341 return (n == 1) ? 0 : (n == 2) ? 1 : (n == 3) ? 2 : 3; 342 case "ga": // Irish 343 // 5 forms 344 return n == 1 ? 0 : n == 2 ? 1 : n < 7 ? 2 : n < 11 ? 3 : 4; 345 case "ar": // Arabic 346 // 6 forms 347 return (n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5); 348 default: // Everything else 349 return n != 1 ? 1 : 0; 350 } 351 } 352});
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.