'use strict'; angular.module('myApp.i18n', ['izhukov.utils']) .factory('_', ['$http', '$route', 'Storage', '$locale', function($http, $route, Storage, $locale) { var locale = 'en-us'; var messages = {}; var fallbackMessages = {}; var supported = { 'en-us': 'English' }; var aliases = { 'en': 'en-us' }; var paramRegEx = /\{\s*([a-zA-Z\d\--]+)(?:\s*:\s*(.*?))?\s*\}/g; function insertParams(msgstr, params) { return msgstr.replace(paramRegEx, function ($0, paramKey, nestedMsgStr) { var param = params[paramKey]; if (param === undefined) { console.warn('[i18n] missing param ' + paramKey + ' for message "' + msgstr + '"'); return ''; } if (nestedMsgStr !== undefined) { param = insertParams(param, nestedMsgStr.split('|')); } return param.toString().trim(); }); } function encodeEntities(value) { return value. replace(/&/g, '&'). replace(/([^\#-~| |!])/g, function (value) { // non-alphanumeric return '&#' + value.charCodeAt(0) + ';'; }). replace(//g, '>'); } function parseMarkdownString(msgstr, msgid) { msgstr = msgstr.replace(/\*\*(.+?)\*\*/g, "$1") .replace(/\n/g, "
"); return msgstr; } function _(msgid, params) { var raw = false; var msgstr = msgid; if (msgid.substr(-4) === '_raw') { raw = true; msgid = msgid.substr(0, msgid.length - 4); } if (messages.hasOwnProperty(msgid)) { msgstr = messages[msgid]; } else if (fallbackMessages.hasOwnProperty(msgid)) { msgstr = fallbackMessages[msgid]; console.warn('[i18n] missing locale key ' + locale + ' / ' + msgid); } else { console.warn('[i18n] missing key ' + msgid); return msgid; } if (!raw) { msgstr = encodeEntities(msgstr); } if (msgid.substr(-3) == '_md') { msgstr = parseMarkdownString(msgstr); } if (arguments.length > 1) { if (typeof params == 'string') { Array.prototype.shift.apply(arguments); msgstr = insertParams(msgstr, arguments); } else { msgstr = insertParams(msgstr, params); } } return msgstr; } _.supported = function() { return supported; }; _.locale = function(newValue) { if (newValue === undefined) { return locale; } if (!supported.hasOwnProperty(newValue)) { newValue = 'en-us'; // fallback } if (locale != newValue) { var newMessages = false; var ngLocaleReady = false; var onReady = function() { if (newMessages === false || ngLocaleReady === false) { // only execute when both - ngLocale and the new messages - are loaded return; } function deepUpdate(oldValue, newValue) { for (var i in newValue) { if (i in oldValue && typeof oldValue[i] === 'object' && i !== null){ deepUpdate(oldValue[i], newValue[i]); } else { oldValue[i] = newValue[i]; } } } // first we need to explizitly request the new $locale so it gets initialized // then we recursively update our current $locale with it so all other modules // already holding a reference to our $locale will get the new values as well // this hack is necessary because ngLocale just isn't designed to be changed at runtime deepUpdate($locale, angular.injector(['ngLocale']).get('$locale')); messages = newMessages; locale = newValue; $route.reload(); }; angular.element('