/*! * angular-translate - v2.4.2 - 2014-10-21 * http://github.com/angular-translate/angular-translate * Copyright (c) 2014 ; Licensed MIT */ angular.module('pascalprecht.translate', ['ng']).run([ '$translate', function ($translate) { var key = $translate.storageKey(), storage = $translate.storage(); if (storage) { if (!storage.get(key)) { if (angular.isString($translate.preferredLanguage())) { $translate.use($translate.preferredLanguage()); } else { storage.set(key, $translate.use()); } } else { $translate.use(storage.get(key)); } } else if (angular.isString($translate.preferredLanguage())) { $translate.use($translate.preferredLanguage()); } } ]); angular.module('pascalprecht.translate').provider('$translate', [ '$STORAGE_KEY', function ($STORAGE_KEY) { var $translationTable = {}, $preferredLanguage, $availableLanguageKeys = [], $languageKeyAliases, $fallbackLanguage, $fallbackWasString, $uses, $nextLang, $storageFactory, $storageKey = $STORAGE_KEY, $storagePrefix, $missingTranslationHandlerFactory, $interpolationFactory, $interpolatorFactories = [], $interpolationSanitizationStrategy = false, $loaderFactory, $cloakClassName = 'translate-cloak', $loaderOptions, $notFoundIndicatorLeft, $notFoundIndicatorRight, $postCompilingEnabled = false, NESTED_OBJECT_DELIMITER = '.', loaderCache; var version = '2.4.2'; var getLocale = function () { var nav = window.navigator; return ((angular.isArray(nav.languages) ? nav.languages[0] : nav.language || nav.browserLanguage || nav.systemLanguage || nav.userLanguage) || '').split('-').join('_'); }; var indexOf = function (array, searchElement) { for (var i = 0, len = array.length; i < len; i++) { if (array[i] === searchElement) { return i; } } return -1; }; var trim = function () { return this.replace(/^\s+|\s+$/g, ''); }; var negotiateLocale = function (preferred) { var avail = [], locale = angular.lowercase(preferred), i = 0, n = $availableLanguageKeys.length; for (; i < n; i++) { avail.push(angular.lowercase($availableLanguageKeys[i])); } if (indexOf(avail, locale) > -1) { return preferred; } if ($languageKeyAliases) { var alias; for (var langKeyAlias in $languageKeyAliases) { var hasWildcardKey = false; var hasExactKey = Object.prototype.hasOwnProperty.call($languageKeyAliases, langKeyAlias) && angular.lowercase(langKeyAlias) === angular.lowercase(preferred); if (langKeyAlias.slice(-1) === '*') { hasWildcardKey = langKeyAlias.slice(0, -1) === preferred.slice(0, langKeyAlias.length - 1); } if (hasExactKey || hasWildcardKey) { alias = $languageKeyAliases[langKeyAlias]; if (indexOf(avail, angular.lowercase(alias)) > -1) { return alias; } } } } var parts = preferred.split('_'); if (parts.length > 1 && indexOf(avail, angular.lowercase(parts[0])) > -1) { return parts[0]; } return preferred; }; var translations = function (langKey, translationTable) { if (!langKey && !translationTable) { return $translationTable; } if (langKey && !translationTable) { if (angular.isString(langKey)) { return $translationTable[langKey]; } } else { if (!angular.isObject($translationTable[langKey])) { $translationTable[langKey] = {}; } angular.extend($translationTable[langKey], flatObject(translationTable)); } return this; }; this.translations = translations; this.cloakClassName = function (name) { if (!name) { return $cloakClassName; } $cloakClassName = name; return this; }; var flatObject = function (data, path, result, prevKey) { var key, keyWithPath, keyWithShortPath, val; if (!path) { path = []; } if (!result) { result = {}; } for (key in data) { if (!Object.prototype.hasOwnProperty.call(data, key)) { continue; } val = data[key]; if (angular.isObject(val)) { flatObject(val, path.concat(key), result, key); } else { keyWithPath = path.length ? '' + path.join(NESTED_OBJECT_DELIMITER) + NESTED_OBJECT_DELIMITER + key : key; if (path.length && key === prevKey) { keyWithShortPath = '' + path.join(NESTED_OBJECT_DELIMITER); result[keyWithShortPath] = '@:' + keyWithPath; } result[keyWithPath] = val; } } return result; }; this.addInterpolation = function (factory) { $interpolatorFactories.push(factory); return this; }; this.useMessageFormatInterpolation = function () { return this.useInterpolation('$translateMessageFormatInterpolation'); }; this.useInterpolation = function (factory) { $interpolationFactory = factory; return this; }; this.useSanitizeValueStrategy = function (value) { $interpolationSanitizationStrategy = value; return this; }; this.preferredLanguage = function (langKey) { setupPreferredLanguage(langKey); return this; }; var setupPreferredLanguage = function (langKey) { if (langKey) { $preferredLanguage = langKey; } return $preferredLanguage; }; this.translationNotFoundIndicator = function (indicator) { this.translationNotFoundIndicatorLeft(indicator); this.translationNotFoundIndicatorRight(indicator); return this; }; this.translationNotFoundIndicatorLeft = function (indicator) { if (!indicator) { return $notFoundIndicatorLeft; } $notFoundIndicatorLeft = indicator; return this; }; this.translationNotFoundIndicatorRight = function (indicator) { if (!indicator) { return $notFoundIndicatorRight; } $notFoundIndicatorRight = indicator; return this; }; this.fallbackLanguage = function (langKey) { fallbackStack(langKey); return this; }; var fallbackStack = function (langKey) { if (langKey) { if (angular.isString(langKey)) { $fallbackWasString = true; $fallbackLanguage = [langKey]; } else if (angular.isArray(langKey)) { $fallbackWasString = false; $fallbackLanguage = langKey; } if (angular.isString($preferredLanguage) && indexOf($fallbackLanguage, $preferredLanguage) < 0) { $fallbackLanguage.push($preferredLanguage); } return this; } else { if ($fallbackWasString) { return $fallbackLanguage[0]; } else { return $fallbackLanguage; } } }; this.use = function (langKey) { if (langKey) { if (!$translationTable[langKey] && !$loaderFactory) { throw new Error('$translateProvider couldn\'t find translationTable for langKey: \'' + langKey + '\''); } $uses = langKey; return this; } return $uses; }; var storageKey = function (key) { if (!key) { if ($storagePrefix) { return $storagePrefix + $storageKey; } return $storageKey; } $storageKey = key; }; this.storageKey = storageKey; this.useUrlLoader = function (url, options) { return this.useLoader('$translateUrlLoader', angular.extend({ url: url }, options)); }; this.useStaticFilesLoader = function (options) { return this.useLoader('$translateStaticFilesLoader', options); }; this.useLoader = function (loaderFactory, options) { $loaderFactory = loaderFactory; $loaderOptions = options || {}; return this; }; this.useLocalStorage = function () { return this.useStorage('$translateLocalStorage'); }; this.useCookieStorage = function () { return this.useStorage('$translateCookieStorage'); }; this.useStorage = function (storageFactory) { $storageFactory = storageFactory; return this; }; this.storagePrefix = function (prefix) { if (!prefix) { return prefix; } $storagePrefix = prefix; return this; }; this.useMissingTranslationHandlerLog = function () { return this.useMissingTranslationHandler('$translateMissingTranslationHandlerLog'); }; this.useMissingTranslationHandler = function (factory) { $missingTranslationHandlerFactory = factory; return this; }; this.usePostCompiling = function (value) { $postCompilingEnabled = !!value; return this; }; this.determinePreferredLanguage = function (fn) { var locale = fn && angular.isFunction(fn) ? fn() : getLocale(); if (!$availableLanguageKeys.length) { $preferredLanguage = locale; } else { $preferredLanguage = negotiateLocale(locale); } return this; }; this.registerAvailableLanguageKeys = function (languageKeys, aliases) { if (languageKeys) { $availableLanguageKeys = languageKeys; if (aliases) { $languageKeyAliases = aliases; } return this; } return $availableLanguageKeys; }; this.useLoaderCache = function (cache) { if (cache === false) { loaderCache = undefined; } else if (cache === true) { loaderCache = true; } else if (typeof cache === 'undefined') { loaderCache = '$translationCache'; } else if (cache) { loaderCache = cache; } return this; }; this.$get = [ '$log', '$injector', '$rootScope', '$q', function ($log, $injector, $rootScope, $q) { var Storage, defaultInterpolator = $injector.get($interpolationFactory || '$translateDefaultInterpolation'), pendingLoader = false, interpolatorHashMap = {}, langPromises = {}, fallbackIndex, startFallbackIteration; var $translate = function (translationId, interpolateParams, interpolationId) { if (angular.isArray(translationId)) { var translateAll = function (translationIds) { var results = {}; var promises = []; var translate = function (translationId) { var deferred = $q.defer(); var regardless = function (value) { results[translationId] = value; deferred.resolve([ translationId, value ]); }; $translate(translationId, interpolateParams, interpolationId).then(regardless, regardless); return deferred.promise; }; for (var i = 0, c = translationIds.length; i < c; i++) { promises.push(translate(translationIds[i])); } return $q.all(promises).then(function () { return results; }); }; return translateAll(translationId); } var deferred = $q.defer(); if (translationId) { translationId = trim.apply(translationId); } var promiseToWaitFor = function () { var promise = $preferredLanguage ? langPromises[$preferredLanguage] : langPromises[$uses]; fallbackIndex = 0; if ($storageFactory && !promise) { var langKey = Storage.get($storageKey); promise = langPromises[langKey]; if ($fallbackLanguage && $fallbackLanguage.length) { var index = indexOf($fallbackLanguage, langKey); fallbackIndex = index === 0 ? 1 : 0; if (indexOf($fallbackLanguage, $preferredLanguage) < 0) { $fallbackLanguage.push($preferredLanguage); } } } return promise; }(); if (!promiseToWaitFor) { determineTranslation(translationId, interpolateParams, interpolationId).then(deferred.resolve, deferred.reject); } else { promiseToWaitFor.then(function () { determineTranslation(translationId, interpolateParams, interpolationId).then(deferred.resolve, deferred.reject); }, deferred.reject); } return deferred.promise; }; var applyNotFoundIndicators = function (translationId) { if ($notFoundIndicatorLeft) { translationId = [ $notFoundIndicatorLeft, translationId ].join(' '); } if ($notFoundIndicatorRight) { translationId = [ translationId, $notFoundIndicatorRight ].join(' '); } return translationId; }; var useLanguage = function (key) { $uses = key; $rootScope.$emit('$translateChangeSuccess', { language: key }); if ($storageFactory) { Storage.set($translate.storageKey(), $uses); } defaultInterpolator.setLocale($uses); angular.forEach(interpolatorHashMap, function (interpolator, id) { interpolatorHashMap[id].setLocale($uses); }); $rootScope.$emit('$translateChangeEnd', { language: key }); }; var loadAsync = function (key) { if (!key) { throw 'No language key specified for loading.'; } var deferred = $q.defer(); $rootScope.$emit('$translateLoadingStart', { language: key }); pendingLoader = true; var cache = loaderCache; if (typeof cache === 'string') { cache = $injector.get(cache); } var loaderOptions = angular.extend({}, $loaderOptions, { key: key, $http: angular.extend({}, { cache: cache }, $loaderOptions.$http) }); $injector.get($loaderFactory)(loaderOptions).then(function (data) { var translationTable = {}; $rootScope.$emit('$translateLoadingSuccess', { language: key }); if (angular.isArray(data)) { angular.forEach(data, function (table) { angular.extend(translationTable, flatObject(table)); }); } else { angular.extend(translationTable, flatObject(data)); } pendingLoader = false; deferred.resolve({ key: key, table: translationTable }); $rootScope.$emit('$translateLoadingEnd', { language: key }); }, function (key) { $rootScope.$emit('$translateLoadingError', { language: key }); deferred.reject(key); $rootScope.$emit('$translateLoadingEnd', { language: key }); }); return deferred.promise; }; if ($storageFactory) { Storage = $injector.get($storageFactory); if (!Storage.get || !Storage.set) { throw new Error('Couldn\'t use storage \'' + $storageFactory + '\', missing get() or set() method!'); } } if (angular.isFunction(defaultInterpolator.useSanitizeValueStrategy)) { defaultInterpolator.useSanitizeValueStrategy($interpolationSanitizationStrategy); } if ($interpolatorFactories.length) { angular.forEach($interpolatorFactories, function (interpolatorFactory) { var interpolator = $injector.get(interpolatorFactory); interpolator.setLocale($preferredLanguage || $uses); if (angular.isFunction(interpolator.useSanitizeValueStrategy)) { interpolator.useSanitizeValueStrategy($interpolationSanitizationStrategy); } interpolatorHashMap[interpolator.getInterpolationIdentifier()] = interpolator; }); } var getTranslationTable = function (langKey) { var deferred = $q.defer(); if (Object.prototype.hasOwnProperty.call($translationTable, langKey)) { deferred.resolve($translationTable[langKey]); } else if (langPromises[langKey]) { langPromises[langKey].then(function (data) { translations(data.key, data.table); deferred.resolve(data.table); }, deferred.reject); } else { deferred.reject(); } return deferred.promise; }; var getFallbackTranslation = function (langKey, translationId, interpolateParams, Interpolator) { var deferred = $q.defer(); getTranslationTable(langKey).then(function (translationTable) { if (Object.prototype.hasOwnProperty.call(translationTable, translationId)) { Interpolator.setLocale(langKey); deferred.resolve(Interpolator.interpolate(translationTable[translationId], interpolateParams)); Interpolator.setLocale($uses); } else { deferred.reject(); } }, deferred.reject); return deferred.promise; }; var getFallbackTranslationInstant = function (langKey, translationId, interpolateParams, Interpolator) { var result, translationTable = $translationTable[langKey]; if (Object.prototype.hasOwnProperty.call(translationTable, translationId)) { Interpolator.setLocale(langKey); result = Interpolator.interpolate(translationTable[translationId], interpolateParams); Interpolator.setLocale($uses); } return result; }; var translateByHandler = function (translationId) { if ($missingTranslationHandlerFactory) { var resultString = $injector.get($missingTranslationHandlerFactory)(translationId, $uses); if (resultString !== undefined) { return resultString; } else { return translationId; } } else { return translationId; } }; var resolveForFallbackLanguage = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator) { var deferred = $q.defer(); if (fallbackLanguageIndex < $fallbackLanguage.length) { var langKey = $fallbackLanguage[fallbackLanguageIndex]; getFallbackTranslation(langKey, translationId, interpolateParams, Interpolator).then(deferred.resolve, function () { resolveForFallbackLanguage(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator).then(deferred.resolve); }); } else { deferred.resolve(translateByHandler(translationId)); } return deferred.promise; }; var resolveForFallbackLanguageInstant = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator) { var result; if (fallbackLanguageIndex < $fallbackLanguage.length) { var langKey = $fallbackLanguage[fallbackLanguageIndex]; result = getFallbackTranslationInstant(langKey, translationId, interpolateParams, Interpolator); if (!result) { result = resolveForFallbackLanguageInstant(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator); } } return result; }; var fallbackTranslation = function (translationId, interpolateParams, Interpolator) { return resolveForFallbackLanguage(startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex, translationId, interpolateParams, Interpolator); }; var fallbackTranslationInstant = function (translationId, interpolateParams, Interpolator) { return resolveForFallbackLanguageInstant(startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex, translationId, interpolateParams, Interpolator); }; var determineTranslation = function (translationId, interpolateParams, interpolationId) { var deferred = $q.defer(); var table = $uses ? $translationTable[$uses] : $translationTable, Interpolator = interpolationId ? interpolatorHashMap[interpolationId] : defaultInterpolator; if (table && Object.prototype.hasOwnProperty.call(table, translationId)) { var translation = table[translationId]; if (translation.substr(0, 2) === '@:') { $translate(translation.substr(2), interpolateParams, interpolationId).then(deferred.resolve, deferred.reject); } else { deferred.resolve(Interpolator.interpolate(translation, interpolateParams)); } } else { var missingTranslationHandlerTranslation; if ($missingTranslationHandlerFactory && !pendingLoader) { missingTranslationHandlerTranslation = translateByHandler(translationId); } if ($uses && $fallbackLanguage && $fallbackLanguage.length) { fallbackTranslation(translationId, interpolateParams, Interpolator).then(function (translation) { deferred.resolve(translation); }, function (_translationId) { deferred.reject(applyNotFoundIndicators(_translationId)); }); } else if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { deferred.resolve(missingTranslationHandlerTranslation); } else { deferred.reject(applyNotFoundIndicators(translationId)); } } return deferred.promise; }; var determineTranslationInstant = function (translationId, interpolateParams, interpolationId) { var result, table = $uses ? $translationTable[$uses] : $translationTable, Interpolator = interpolationId ? interpolatorHashMap[interpolationId] : defaultInterpolator; if (table && Object.prototype.hasOwnProperty.call(table, translationId)) { var translation = table[translationId]; if (translation.substr(0, 2) === '@:') { result = determineTranslationInstant(translation.substr(2), interpolateParams, interpolationId); } else { result = Interpolator.interpolate(translation, interpolateParams); } } else { var missingTranslationHandlerTranslation; if ($missingTranslationHandlerFactory && !pendingLoader) { missingTranslationHandlerTranslation = translateByHandler(translationId); } if ($uses && $fallbackLanguage && $fallbackLanguage.length) { fallbackIndex = 0; result = fallbackTranslationInstant(translationId, interpolateParams, Interpolator); } else if ($missingTranslationHandlerFactory && !pendingLoader && missingTranslationHandlerTranslation) { result = missingTranslationHandlerTranslation; } else { result = applyNotFoundIndicators(translationId); } } return result; }; $translate.preferredLanguage = function (langKey) { if (langKey) { setupPreferredLanguage(langKey); } return $preferredLanguage; }; $translate.cloakClassName = function () { return $cloakClassName; }; $translate.fallbackLanguage = function (langKey) { if (langKey !== undefined && langKey !== null) { fallbackStack(langKey); if ($loaderFactory) { if ($fallbackLanguage && $fallbackLanguage.length) { for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { if (!langPromises[$fallbackLanguage[i]]) { langPromises[$fallbackLanguage[i]] = loadAsync($fallbackLanguage[i]); } } } } $translate.use($translate.use()); } if ($fallbackWasString) { return $fallbackLanguage[0]; } else { return $fallbackLanguage; } }; $translate.useFallbackLanguage = function (langKey) { if (langKey !== undefined && langKey !== null) { if (!langKey) { startFallbackIteration = 0; } else { var langKeyPosition = indexOf($fallbackLanguage, langKey); if (langKeyPosition > -1) { startFallbackIteration = langKeyPosition; } } } }; $translate.proposedLanguage = function () { return $nextLang; }; $translate.storage = function () { return Storage; }; $translate.use = function (key) { if (!key) { return $uses; } var deferred = $q.defer(); $rootScope.$emit('$translateChangeStart', { language: key }); var aliasedKey = negotiateLocale(key); if (aliasedKey) { key = aliasedKey; } if (!$translationTable[key] && $loaderFactory && !langPromises[key]) { $nextLang = key; langPromises[key] = loadAsync(key).then(function (translation) { translations(translation.key, translation.table); deferred.resolve(translation.key); useLanguage(translation.key); if ($nextLang === key) { $nextLang = undefined; } }, function (key) { if ($nextLang === key) { $nextLang = undefined; } $rootScope.$emit('$translateChangeError', { language: key }); deferred.reject(key); $rootScope.$emit('$translateChangeEnd', { language: key }); }); } else { deferred.resolve(key); useLanguage(key); } return deferred.promise; }; $translate.storageKey = function () { return storageKey(); }; $translate.isPostCompilingEnabled = function () { return $postCompilingEnabled; }; $translate.refresh = function (langKey) { if (!$loaderFactory) { throw new Error('Couldn\'t refresh translation table, no loader registered!'); } var deferred = $q.defer(); function resolve() { deferred.resolve(); $rootScope.$emit('$translateRefreshEnd', { language: langKey }); } function reject() { deferred.reject(); $rootScope.$emit('$translateRefreshEnd', { language: langKey }); } $rootScope.$emit('$translateRefreshStart', { language: langKey }); if (!langKey) { var tables = [], loadingKeys = {}; if ($fallbackLanguage && $fallbackLanguage.length) { for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { tables.push(loadAsync($fallbackLanguage[i])); loadingKeys[$fallbackLanguage[i]] = true; } } if ($uses && !loadingKeys[$uses]) { tables.push(loadAsync($uses)); } $q.all(tables).then(function (tableData) { angular.forEach(tableData, function (data) { if ($translationTable[data.key]) { delete $translationTable[data.key]; } translations(data.key, data.table); }); if ($uses) { useLanguage($uses); } resolve(); }); } else if ($translationTable[langKey]) { loadAsync(langKey).then(function (data) { translations(data.key, data.table); if (langKey === $uses) { useLanguage($uses); } resolve(); }, reject); } else { reject(); } return deferred.promise; }; $translate.instant = function (translationId, interpolateParams, interpolationId) { if (translationId === null || angular.isUndefined(translationId)) { return translationId; } if (angular.isArray(translationId)) { var results = {}; for (var i = 0, c = translationId.length; i < c; i++) { results[translationId[i]] = $translate.instant(translationId[i], interpolateParams, interpolationId); } return results; } if (angular.isString(translationId) && translationId.length < 1) { return translationId; } if (translationId) { translationId = trim.apply(translationId); } var result, possibleLangKeys = []; if ($preferredLanguage) { possibleLangKeys.push($preferredLanguage); } if ($uses) { possibleLangKeys.push($uses); } if ($fallbackLanguage && $fallbackLanguage.length) { possibleLangKeys = possibleLangKeys.concat($fallbackLanguage); } for (var j = 0, d = possibleLangKeys.length; j < d; j++) { var possibleLangKey = possibleLangKeys[j]; if ($translationTable[possibleLangKey]) { if (typeof $translationTable[possibleLangKey][translationId] !== 'undefined') { result = determineTranslationInstant(translationId, interpolateParams, interpolationId); } } if (typeof result !== 'undefined') { break; } } if (!result && result !== '') { result = defaultInterpolator.interpolate(translationId, interpolateParams); if ($missingTranslationHandlerFactory && !pendingLoader) { result = translateByHandler(translationId); } } return result; }; $translate.versionInfo = function () { return version; }; $translate.loaderCache = function () { return loaderCache; }; if ($loaderFactory) { if (angular.equals($translationTable, {})) { $translate.use($translate.use()); } if ($fallbackLanguage && $fallbackLanguage.length) { var processAsyncResult = function (translation) { translations(translation.key, translation.table); $rootScope.$emit('$translateChangeEnd', { language: translation.key }); }; for (var i = 0, len = $fallbackLanguage.length; i < len; i++) { langPromises[$fallbackLanguage[i]] = loadAsync($fallbackLanguage[i]).then(processAsyncResult); } } } return $translate; } ]; } ]); angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation', [ '$interpolate', function ($interpolate) { var $translateInterpolator = {}, $locale, $identifier = 'default', $sanitizeValueStrategy = null, sanitizeValueStrategies = { escaped: function (params) { var result = {}; for (var key in params) { if (Object.prototype.hasOwnProperty.call(params, key)) { result[key] = angular.element('
').text(params[key]).html(); } } return result; } }; var sanitizeParams = function (params) { var result; if (angular.isFunction(sanitizeValueStrategies[$sanitizeValueStrategy])) { result = sanitizeValueStrategies[$sanitizeValueStrategy](params); } else { result = params; } return result; }; $translateInterpolator.setLocale = function (locale) { $locale = locale; }; $translateInterpolator.getInterpolationIdentifier = function () { return $identifier; }; $translateInterpolator.useSanitizeValueStrategy = function (value) { $sanitizeValueStrategy = value; return this; }; $translateInterpolator.interpolate = function (string, interpolateParams) { if ($sanitizeValueStrategy) { interpolateParams = sanitizeParams(interpolateParams); } return $interpolate(string)(interpolateParams || {}); }; return $translateInterpolator; } ]); angular.module('pascalprecht.translate').constant('$STORAGE_KEY', 'NG_TRANSLATE_LANG_KEY'); angular.module('pascalprecht.translate').directive('translate', [ '$translate', '$q', '$interpolate', '$compile', '$parse', '$rootScope', function ($translate, $q, $interpolate, $compile, $parse, $rootScope) { return { restrict: 'AE', scope: true, compile: function (tElement, tAttr) { var translateValuesExist = tAttr.translateValues ? tAttr.translateValues : undefined; var translateInterpolation = tAttr.translateInterpolation ? tAttr.translateInterpolation : undefined; var translateValueExist = tElement[0].outerHTML.match(/translate-value-+/i); var interpolateRegExp = '^(.*)(' + $interpolate.startSymbol() + '.*' + $interpolate.endSymbol() + ')(.*)'; return function linkFn(scope, iElement, iAttr) { scope.interpolateParams = {}; scope.preText = ''; scope.postText = ''; iAttr.$observe('translate', function (translationId) { if (angular.equals(translationId, '') || !angular.isDefined(translationId)) { var interpolateMatches = iElement.text().match(interpolateRegExp); if (angular.isArray(interpolateMatches)) { scope.preText = interpolateMatches[1]; scope.postText = interpolateMatches[3]; scope.translationId = $interpolate(interpolateMatches[2])(scope.$parent); } else { scope.translationId = iElement.text().replace(/^\s+|\s+$/g, ''); } } else { scope.translationId = translationId; } }); iAttr.$observe('translateDefault', function (value) { scope.defaultText = value; }); if (translateValuesExist) { iAttr.$observe('translateValues', function (interpolateParams) { if (interpolateParams) { scope.$parent.$watch(function () { angular.extend(scope.interpolateParams, $parse(interpolateParams)(scope.$parent)); }); } }); } if (translateValueExist) { var fn = function (attrName) { iAttr.$observe(attrName, function (value) { scope.interpolateParams[angular.lowercase(attrName.substr(14, 1)) + attrName.substr(15)] = value; }); }; for (var attr in iAttr) { if (Object.prototype.hasOwnProperty.call(iAttr, attr) && attr.substr(0, 14) === 'translateValue' && attr !== 'translateValues') { fn(attr); } } } var applyElementContent = function (value, scope, successful) { if (!successful && typeof scope.defaultText !== 'undefined') { value = scope.defaultText; } iElement.html(scope.preText + value + scope.postText); var globallyEnabled = $translate.isPostCompilingEnabled(); var locallyDefined = typeof tAttr.translateCompile !== 'undefined'; var locallyEnabled = locallyDefined && tAttr.translateCompile !== 'false'; if (globallyEnabled && !locallyDefined || locallyEnabled) { $compile(iElement.contents())(scope); } }; var updateTranslationFn = function () { if (!translateValuesExist && !translateValueExist) { return function () { var unwatch = scope.$watch('translationId', function (value) { if (scope.translationId && value) { $translate(value, {}, translateInterpolation).then(function (translation) { applyElementContent(translation, scope, true); unwatch(); }, function (translationId) { applyElementContent(translationId, scope, false); unwatch(); }); } }, true); }; } else { return function () { var updateTranslations = function () { if (scope.translationId && scope.interpolateParams) { $translate(scope.translationId, scope.interpolateParams, translateInterpolation).then(function (translation) { applyElementContent(translation, scope, true); }, function (translationId) { applyElementContent(translationId, scope, false); }); } }; scope.$watch('interpolateParams', updateTranslations, true); scope.$watch('translationId', updateTranslations); }; } }(); var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslationFn); updateTranslationFn(); scope.$on('$destroy', unbind); }; } }; } ]); angular.module('pascalprecht.translate').directive('translateCloak', [ '$rootScope', '$translate', function ($rootScope, $translate) { return { compile: function (tElement) { var applyCloak = function () { tElement.addClass($translate.cloakClassName()); }, removeCloak = function () { tElement.removeClass($translate.cloakClassName()); }, removeListener = $rootScope.$on('$translateChangeEnd', function () { removeCloak(); removeListener(); removeListener = null; }); applyCloak(); return function linkFn(scope, iElement, iAttr) { if (iAttr.translateCloak && iAttr.translateCloak.length) { iAttr.$observe('translateCloak', function (translationId) { $translate(translationId).then(removeCloak, applyCloak); }); } }; } }; } ]); angular.module('pascalprecht.translate').filter('translate', [ '$parse', '$translate', function ($parse, $translate) { var translateFilter = function (translationId, interpolateParams, interpolation) { if (!angular.isObject(interpolateParams)) { interpolateParams = $parse(interpolateParams)(this); } return $translate.instant(translationId, interpolateParams, interpolation); }; translateFilter.$stateful = true; return translateFilter; } ]);