app/assets/javascripts/i18n.js in i18n-js-3.0.0.rc14 vs app/assets/javascripts/i18n.js in i18n-js-3.0.0.rc15

- old
+ new

@@ -51,17 +51,29 @@ return type === 'function' || type === 'object' && !!obj; }; // Is a given value an array? // Borrowed from Underscore.js - var isArray = function(obj) { + var isArray = function(val) { if (Array.isArray) { - return Array.isArray(obj); + return Array.isArray(val); }; - return Object.prototype.toString.call(obj) === '[object Array]'; + return Object.prototype.toString.call(val) === '[object Array]'; }; + var isString = function(val) { + return typeof value == 'string' || Object.prototype.toString.call(val) === '[object String]'; + }; + + var isNumber = function(val) { + return typeof val == 'number' || Object.prototype.toString.call(val) === '[object Number]'; + }; + + var isBoolean = function(val) { + return val === true || val === false; + }; + var decimalAdjust = function(type, value, exp) { // If the exp is undefined or zero... if (typeof exp === 'undefined' || +exp === 0) { return Math[type](value); } @@ -81,11 +93,11 @@ var merge = function (dest, obj) { var key, value; for (key in obj) if (obj.hasOwnProperty(key)) { value = obj[key]; - if (Object.prototype.toString.call(value) === '[object String]') { + if (isString(value) || isNumber(value) || isBoolean(value)) { dest[key] = value; } else { if (dest[key] == null) dest[key] = {}; merge(dest[key], value); } @@ -345,11 +357,10 @@ translations = this.translations[locale]; if (!translations) { continue; } - while (scopes.length) { translations = translations[scopes.shift()]; if (translations === undefined || translations === null) { break; @@ -364,10 +375,79 @@ if (this.isSet(options.defaultValue)) { return options.defaultValue; } }; + // lookup pluralization rule key into translations + I18n.pluralizationLookupWithoutFallback = function(count, locale, translations) { + var pluralizer = this.pluralization.get(locale) + , pluralizerKeys = pluralizer(count) + , pluralizerKey + , message; + + if (isObject(translations)) { + while (pluralizerKeys.length) { + pluralizerKey = pluralizerKeys.shift(); + if (this.isSet(translations[pluralizerKey])) { + message = translations[pluralizerKey]; + break; + } + } + } + + return message; + }; + + // Lookup dedicated to pluralization + I18n.pluralizationLookup = function(count, scope, options) { + options = this.prepareOptions(options); + var locales = this.locales.get(options.locale).slice() + , requestedLocale = locales[0] + , locale + , scopes + , translations + , message + ; + scope = this.getFullScope(scope, options); + + while (locales.length) { + locale = locales.shift(); + scopes = scope.split(this.defaultSeparator); + translations = this.translations[locale]; + + if (!translations) { + continue; + } + + while (scopes.length) { + translations = translations[scopes.shift()]; + if (!isObject(translations)) { + break; + } + if (scopes.length == 0) { + message = this.pluralizationLookupWithoutFallback(count, locale, translations); + } + } + if (message != null && message != undefined) { + break; + } + } + + if (message == null || message == undefined) { + if (this.isSet(options.defaultValue)) { + if (isObject(options.defaultValue)) { + message = this.pluralizationLookupWithoutFallback(count, options.locale, options.defaultValue); + } else { + message = options.defaultValue; + } + translations = options.defaultValue; + } + } + + return { message: message, translations: translations }; + }; + // Rails changed the way the meridian is stored. // It started with `date.meridian` returning an array, // then it switched to `time.am` and `time.pm`. // This function abstracts this difference and returns // the correct meridian or the default value when none is provided. @@ -468,11 +548,11 @@ } if (typeof(translation) === "string") { translation = this.interpolate(translation, options); } else if (isObject(translation) && this.isSet(options.count)) { - translation = this.pluralize(options.count, translation, options); + translation = this.pluralize(options.count, scope, options); } return translation; }; @@ -514,35 +594,25 @@ // Pluralize the given scope using the `count` value. // The pluralized translation may have other placeholders, // which will be retrieved from `options`. I18n.pluralize = function(count, scope, options) { options = this.prepareOptions(options); - var translations, pluralizer, keys, key, message; + var pluralizer, message, result; - if (isObject(scope)) { - translations = scope; - } else { - translations = this.lookup(scope, options); - } - - if (!translations) { + result = this.pluralizationLookup(count, scope, options); + if (result.translations == undefined || result.translations == null) { return this.missingTranslation(scope, options); } - pluralizer = this.pluralization.get(options.locale); - keys = pluralizer(count); + options.count = String(count); - while (keys.length) { - key = keys.shift(); - - if (this.isSet(translations[key])) { - message = translations[key]; - break; - } + if (result.message != undefined && result.message != null) { + return this.interpolate(result.message, options); } - - options.count = String(count); - return this.interpolate(message, options); + else { + pluralizer = this.pluralization.get(options.locale); + return this.missingTranslation(scope + '.' + pluralizer(count)[0], options); + } }; // Return a missing translation message for the given parameters. I18n.missingTranslation = function(scope, options) { //guess intended string