'use strict'; angular.module('myApp.i18n', ['izhukov.utils']) .factory('_', ['$rootScope', '$locale', function($rootScope, $locale) { var locale = Config.I18n.locale; var messages = Config.I18n.messages; var fallbackMessages = Config.I18n.fallback_messages; 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 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; } _.locale = function () { return locale; }; _.pluralize = function (msgid) { var categories = $rootScope.$eval(_(msgid + '_raw')); return function (count) { return (categories[$locale.pluralCat(count)] || '').replace('{}', count); } }; return _; }]) .filter('i18n', ['_', function(_) { return function (msgid, params) { return _(msgid + '_raw', params); } }]) .directive('ngPluralize', ['_', function(_) { return { restrict: 'EA', priority: 1, // execute before built-in ngPluralize compile: function(element) { var msgid = element.attr('when'); var msgstr = _(msgid + '_raw'); element.attr('when', msgstr); } } }]) .directive('myI18n', ['_', function(_) { return { restrict: 'EA', compile: function(element) { var params = element.children('my-i18n-param:not([name]), [my-i18n-param=""]:not([name])').map(function(index, param) { return param.outerHTML; }).toArray(); element.children('my-i18n-param[name], [my-i18n-param]:not([my-i18n-param=""]), [my-i18n-param][name]').each(function(i, param) { params[angular.element(param).attr('my-i18n-param') || angular.element(param).attr('name')] = param.outerHTML; }); element.children('my-i18n-param').remove(); var formats = element.attr("my-i18n") || element.attr("msgid") ? element : element.children('my-i18n-format, [my-i18n-format]'); formats.each(function(index, element) { var format = angular.element(element); var msgid = format.attr("my-i18n") || format.attr("msgid") || format.attr("my-i18n-format") || format.html().replace(/\s+/g, ' ').trim(); var msgstr = _(msgid, params); format.html(msgstr); }); } } }]);