From f102417791c7107c5ec5f1a59076a5fbe29e5a25 Mon Sep 17 00:00:00 2001 From: Santhosh Thottingal Date: Mon, 24 Sep 2012 23:14:33 -0700 Subject: [PATCH] Update jquery.i18n from upstream Change-Id: I08eca83de39963b03e6b25b12cf1992f42c047e2 --- lib/jquery.i18n.js | 1251 +++++++++++++++++++++++--------------------- 1 file changed, 642 insertions(+), 609 deletions(-) diff --git a/lib/jquery.i18n.js b/lib/jquery.i18n.js index 860f2f4d..d8d2cfe9 100644 --- a/lib/jquery.i18n.js +++ b/lib/jquery.i18n.js @@ -13,77 +13,111 @@ * @licence MIT License */ -( function ( $, window, undefined ) { - "use strict"; +( function ( $ ) { + 'use strict'; + var nav, + slice = Array.prototype.slice; + /** + * @constructor + * @param {Object} options + */ var I18N = function ( options ) { // Load defaults - this.options = $.extend( {}, $.i18n.defaults, options ); + this.options = $.extend( {}, I18N.defaults, options ); + this.parser = this.options.parser; + this.locale = this.options.locale; this.messageStore = this.options.messageStore; this.languages = {}; - this.locale = this.options.locale; + this.init(); }; I18N.prototype = { /** - * Initialize by loading locales and setting up toLocaleString + * Initialize by loading locales and setting up + * String.prototype.toLocaleString and String.locale. */ init: function () { - var that = this; - this.messageStore.init( this.locale ); + var i18n; + + i18n = this; + i18n.messageStore.init( i18n.locale ); + // Set locale of String environment + String.locale = i18n.locale; + // Override String.localeString method String.prototype.toLocaleString = function () { - var value = this.valueOf(); - var locale = that.locale; - var fallbackIndex = 0; + var localeParts, localePartIndex, value, locale, fallbackIndex; + + value = this.valueOf(); + locale = i18n.locale; + fallbackIndex = 0; + while ( locale ) { // Iterate through locales starting at most-specific until // localization is found. As in fi-Latn-FI, fi-Latn and fi. - var localeParts = locale.toLowerCase().split( "-" ); - var localePartIndex = localeParts.length; + localeParts = locale.toLowerCase().split( "-" ); + localePartIndex = localeParts.length; + do { var _locale = localeParts.slice( 0, localePartIndex ).join( "-" ); - if ( !that.messageStore.messages[_locale] && that.options.messageLocationResolver ) { + + if ( !i18n.messageStore.messages[_locale] && i18n.options.messageLocationResolver ) { // FIXME If messageloading gives 404, it keep on trying to // load the file again and again - that.messageStore.load( - that.options.messageLocationResolver( _locale ), _locale ); + i18n.messageStore.load( + i18n.options.messageLocationResolver( _locale ), + _locale + ); } - var message = that.messageStore.get( _locale, value ); + + var message = i18n.messageStore.get( _locale, value ); if ( message ) { return message; } localePartIndex--; } while (localePartIndex); + if ( locale === "en" ) { break; } - locale = ( $.i18n.fallbacks[that.locale] && $.i18n.fallbacks[that.locale][fallbackIndex] ) - || that.options.fallbackLocale; - that.log( "Trying fallback locale for " + that.locale + ": " + locale ); + + locale = ( $.i18n.fallbacks[i18n.locale] && $.i18n.fallbacks[i18n.locale][fallbackIndex] ) + || i18n.options.fallbackLocale; + i18n.log( "Trying fallback locale for " + i18n.locale + ": " + locale ); + fallbackIndex++; } - return value; // fallback the original string value + + // fallback the original string value + return value; }; - String.locale = this.locale; }, + /* + * Destroy the i18n instance. + */ destroy: function () { - $( 'body' ).data( 'i18n', null ); + $.removeData( document, 'i18n' ); }, /** - * General message loading API This can take a URL string for the json formatted messages. - * Eg: load('path/to/all_localizations.json'); + * General message loading API This can take a URL string for + * the json formatted messages. + * load('path/to/all_localizations.json'); * - * This can also load a localization file for a locale Eg: load('path/to/de-messages.json', - * 'de' ); - * - * A data object containing message key- message translation mappings can also be passed Eg: - * load( { 'hello' : 'Hello' }, optionalLocale ); If the data argument is - * null/undefined/false, all cached messages for the i18n instance will get reset. + * This can also load a localization file for a locale + * load('path/to/de-messages.json', 'de' ); + * + * A data object containing message key- message translation mappings + * can also be passed Eg: + * + * load( { 'hello' : 'Hello' }, optionalLocale ); + * If the data argument is + * null/undefined/false, + * all cached messages for the i18n instance will get reset. * * @param {String|Object|null} data * @param {String} locale Language tag @@ -93,75 +127,68 @@ }, log: function (/* arguments */) { - var hasConsole = window.console !== undefined; - if ( hasConsole && $.i18n.debug ) { + if ( window.console && $.i18n.debug ) { window.console.log.apply( window.console, arguments ); } }, /** - * Does parameter and magic word substitution. - * - * @param {String} - * key Message key - * @param {Array} - * parameters Message parameters - * @return - * @string - */ + * Does parameter and magic word substitution. + * + * @param {string} key Message key + * @param {Array} parameters Message parameters + * @return {string} + */ parse: function ( key, parameters ) { var message = key.toLocaleString(); + // FIXME: This changes the state of the I18N object, + // should probably not change the 'this.parser' but just + // pass it to the parser. this.parser.language = $.i18n.languages[$.i18n().locale] || $.i18n.languages['default']; return this.parser.parse( message, parameters ); } }; - String.locale = String.locale || $( 'html' ).attr( 'lang' ); - if ( !String.locale ) { - if ( typeof window.navigator !== undefined ) { - var nav = window.navigator; - String.locale = nav.language || nav.userLanguage || ""; - } else { - String.locale = ""; - } - } - - $.i18n = function ( key, parameter_1 /* [, parameter_2] */) { - var parameters = [], i18n = $( 'body' ).data( 'i18n' ); - var options = typeof key === 'object' && key; + /** + * Process a message from the $.I18N instance + * for the current document, stored in jQuery.data(document). + * + * @param {string} key Key of the message. + * @param {string} [param...] Variadic list of parameters for {key}. + * @return {string|$.I18N} Parsed message, or if no key was given + * the instance of $.I18N is returned. + */ + $.i18n = function ( key, param1 ) { + var parameters, + i18n = $.data( document, 'i18n' ), + options = typeof key === 'object' && key; + // If the locale option for this call is different then the setup so far, + // update it automatically. This doesn't just change the context for this + // call but for all future call as well. + // If there is no i18n setup yet, don't do this. It will be taken care of + // by the `new I18N` construction below. + // NOTE: It should only change language for this one call. + // Then cache instances of I18N somewhere. if ( options && options.locale && i18n && i18n.locale !== options.locale ) { String.locale = i18n.locale = options.locale; } if ( !i18n ) { - $( 'body' ).data( 'i18n', ( i18n = new I18N( options ) ) ); - $( '[data-i18n]' ).each( function ( e ) { - var $this = $( this ); - if ( $this.data( 'i18n' ) ) { - var messageKey = $this.data( 'i18n' ); - var message = $.i18n( messageKey ); - if ( message !== messageKey ) { - $this.text( message ); - } - } - } ); - } - - if ( !key ) { - return i18n; - } - - // Support variadic arguments - if ( parameter_1 !== undefined ) { - parameters = $.makeArray( arguments ); - parameters.shift(); + i18n = new I18N( options ); + $.data( document, 'i18n', i18n ); } if ( typeof key === 'string' ) { + if ( param1 !== undefined ) { + parameters = slice.call( arguments, 1 ); + } else { + parameters = []; + } return i18n.parse( key, parameters ); } else { + // FIXME: remove this feature/bug. return i18n; } }; @@ -182,22 +209,33 @@ } ); }; - // The default parser only handles variable substitution - var defaultParser = { + String.locale = String.locale || $( 'html' ).attr( 'lang' ); + if ( !String.locale ) { + if ( typeof window.navigator !== undefined ) { + nav = window.navigator; + String.locale = nav.language || nav.userLanguage || ''; + } else { + String.locale = ''; + } + } + + $.i18n.languages = {}; + $.i18n.messageStore = $.i18n.messageStore || {}; + $.i18n.parser = { + // The default parser only handles variable substitution parse: function ( message, parameters ) { return message.replace( /\$(\d+)/g, function ( str, match ) { var index = parseInt( match, 10 ) - 1; return parameters[index] !== undefined ? parameters[index] : '$' + match; } ); - } + }, + emitter: {} }; - $.i18n.languages = {}; - $.i18n.messageStore = $.i18n.messageStore || {}; - $.i18n.parser = defaultParser; - $.i18n.parser.emitter = {}; $.i18n.debug = false; - $.i18n.defaults = { + + /* Static members */ + I18N.defaults = { locale: String.locale, fallbackLocale: "en", parser: $.i18n.parser, @@ -208,14 +246,9 @@ messageLocationResolver: null }; - $.i18n.Constructor = I18N; - - /** - * Convenient alias - */ - window._ = window._ || $.i18n; - -}( jQuery, window ) ); + // Expose constructor + $.I18N = I18N; +}( jQuery ) ); /** * jQuery Internationalization library Message loading , parsing, retrieving utilities @@ -249,89 +282,100 @@ */ init: function ( locale ) { this.locale = locale; - var that = this; + var messageStore = this; + messageStore.log( "initializing for " + locale ); var $links = $( "link" ); var linksCount = $links.length; - this.log( "initializing for " + locale ); // Check for load('path/to/all_localizations.json'); * * This can also load a localization file for a locale * load('path/to/de-messages.json', 'de' ); * - * A data object containing message key- message translation mappings can also be passed Eg: + * A data object containing message key- message translation mappings + * can also be passed Eg: * * load( { 'hello' : 'Hello' }, optionalLocale ); * If the data argument is - * null/undefined/false, all cached messages for the i18n instance will get reset. + * null/undefined/false, + * all cached messages for the i18n instance will get reset. * * @param {String|Object|null} data * @param {String} locale Language tag */ load: function ( data, locale ) { - var that = this; - var hasOwn = Object.prototype.hasOwnProperty; + var key = null, + messageStore = this, + hasOwn = Object.prototype.hasOwnProperty; + if ( !data ) { // reset all localizations - this.log( "Resetting for locale" + locale ); - that.messages = {}; + messageStore.log( "Resetting for locale" + locale ); + messageStore.messages = {}; return; } - var dataType = typeof data; - if ( locale && this.locale !== locale ) { + + // Only process this data load if the locale is our current + // locale. Otherwise, put in the source queue for later. + if ( locale && messageStore.locale !== locale ) { // queue loading locale if not needed - if ( ! ( locale in this.sources ) ) { - this.sources[locale] = []; + if ( ! ( locale in messageStore.sources ) ) { + messageStore.sources[locale] = []; } - this.log( "Queueing: " + locale + " Current locale " + this.locale ); - this.sources[locale].push( data ); + messageStore.log( "Queueing: " + locale + " Current locale " + messageStore.locale ); + messageStore.sources[locale].push( data ); return; } - if ( arguments.length > 0 && dataType !== "number" ) { - if ( dataType === "string" ) { - // This is a URL to the messages file. - this.log( "Loading messages from: " + data ); - this.jsonMessageLoader( data ).done( function ( localization, textStatus ) { - that.load( localization, locale ); - delete that.sources[locale]; - } ); - } else { - // data is Object - // Extend current localizations instead of completely - // overwriting them - var localization = data; - for ( var messageKey in localization ) { - if ( !hasOwn.call( localization, messageKey ) ) { - continue; - } - var messageKeyType = typeof messageKey; - if ( messageKeyType === "string" && locale ) { - that.log( "[" + locale + "][" + messageKey + "] : " - + localization[messageKey] ); - that.messages[locale] = that.messages[locale] || []; - that.messages[locale][messageKey] = localization[messageKey]; + + if ( typeof data === 'string' ) { + // This is a URL to the messages file. + messageStore.log( "Loading messages from: " + data ); + messageStore.jsonMessageLoader( data ).done( function ( localization, textStatus ) { + messageStore.load( localization, locale ); + delete messageStore.sources[locale]; + } ); + } else { + // Data is either a group of messages for {locale}, + // or a group of languages with groups of messages inside. + for ( key in data) { + if ( hasOwn.call( data, key ) ) { + if ( locale ) { + + // Lazy-init the object + if ( !messageStore.messages[locale] ) { + messageStore.messages[locale] = {}; + } + + // Update message object keys, + // don't overwrite the entire object. + messageStore.messages[locale][key] = data[key]; + + messageStore.log( "[" + locale + "][" + key + "] : " + + data[key] ); + + // No {locale} given, assume data is a group of languages, + // call this function again for each langauge. } else { - var passedLocale = messageKey; - this.log( "Loading locale: " + passedLocale ); - that.load( localization[passedLocale], passedLocale ); + messageStore.load( data[key], key ); } } } @@ -339,8 +383,7 @@ }, log: function (/* arguments */) { - var hasConsole = window.console !== undefined; - if ( hasConsole && $.i18n.debug ) { + if ( window.console && $.i18n.debug ) { window.console.log.apply( window.console, arguments ); } }, @@ -351,12 +394,12 @@ * @param {String} locale */ loadFromQueue: function ( locale ) { - var that = this; - var queue = that.sources[locale]; - for ( var i = 0; i < queue.length; i++ ) { - that.load( queue[i], locale ); + var i, + queue = this.sources[locale]; + for ( i = 0; i < queue.length; i++ ) { + this.load( queue[i], locale ); } - delete that.sources[locale]; + delete this.sources[locale]; }, jsonMessageLoader: function ( url ) { @@ -591,11 +634,11 @@ */ ( function ( $ ) { - "use strict"; + 'use strict'; var MessageParser = function ( options ) { this.options = $.extend( {}, $.i18n.parser.defaults, options ); - this.language = $.i18n.languages[$.i18n().locale]; + this.language = $.i18n.languages[String.locale] || $.i18n.languages['default']; this.emitter = $.i18n.parser.emitter; }; @@ -614,8 +657,9 @@ if ( message.indexOf( '{{' ) < 0 ) { return this.simpleParse( message, replacements ); } - this.emitter.language = $.i18n.languages[$.i18n().locale] - || $.i18n.languages['default']; + this.emitter.language = $.i18n.languages[$.i18n().locale] || + $.i18n.languages['default']; + return this.emitter.emit( this.ast( message ), replacements ); }, @@ -639,10 +683,11 @@ // All must succeed; otherwise, return null. // This is the only eager one. function sequence ( parserSyntax ) { - var originalPos = pos; - var result = []; - for ( var i = 0; i < parserSyntax.length; i++) { - var res = parserSyntax[i](); + var i, res, + originalPos = pos, + result = []; + for ( i = 0; i < parserSyntax.length; i++) { + res = parserSyntax[i](); if ( res === null ) { pos = originalPos; return null; @@ -698,7 +743,7 @@ var pipe = makeStringParser( '|' ); var colon = makeStringParser( ':' ); - var backslash = makeStringParser( "\\" ); + var backslash = makeStringParser( '\\' ); var anyCharacter = makeRegexParser( /^./ ); var dollar = makeStringParser( '$' ); var digits = makeRegexParser( /^\d+/ ); @@ -718,13 +763,6 @@ }; } - // Used to define "literals" without spaces, in space-delimited - // situations - function literalWithoutSpace () { - var result = nOrMore( 1, escapedOrLiteralWithoutSpace )(); - return result === null ? null : result.join( '' ); - } - // Used to define "literals" within template parameters. The pipe // character is the parameter delimeter, so by default // it is not a literal in the parameter @@ -743,7 +781,7 @@ return result === null ? null : result[1]; } - var escapedOrLiteralWithoutSpace = choice( [ escapedLiteral, regularLiteralWithoutSpace ] ); + choice( [ escapedLiteral, regularLiteralWithoutSpace ] ); var escapedOrLiteralWithoutBar = choice( [ escapedLiteral, regularLiteralWithoutBar ] ); var escapedOrRegularLiteral = choice( [ escapedLiteral, regularLiteral ] ); @@ -771,7 +809,7 @@ var expr = result[1]; // use a "CONCAT" operator if there are multiple nodes, // otherwise return the first node, raw. - return expr.length > 1 ? [ "CONCAT" ].concat( expr ) : expr[0]; + return expr.length > 1 ? [ 'CONCAT' ].concat( expr ) : expr[0]; } function templateWithReplacement () { @@ -824,7 +862,7 @@ return null; } - return [ "CONCAT" ].concat( result ); + return [ 'CONCAT' ].concat( result ); } var result = start(); @@ -839,43 +877,42 @@ /** * jQuery Internationalization library - * + * * Copyright (C) 2012 Santhosh Thottingal - * + * * jquery.i18n is dual licensed GPLv2 or later and MIT. You don't have to do * anything special to choose one license or the other and you don't have to * notify anyone which license you are using. You are free to use * UniversalLanguageSelector in commercial projects as long as the copyright * header is left intact. See files GPL-LICENSE and MIT-LICENSE for details. - * + * * @licence GNU General Public Licence 2.0 or later * @licence MIT License */ ( function ( $ ) { - "use strict"; + 'use strict'; var MessageParserEmitter = function () { - this.language = $.i18n.languages[$.i18n().locale] || $.i18n.languages['default']; + this.language = $.i18n.languages[String.locale] || $.i18n.languages['default']; }; MessageParserEmitter.prototype = { constructor: MessageParserEmitter, + /** * (We put this method definition here, and not in prototype, to make * sure it's not overwritten by any magic.) Walk entire node structure, * applying replacements and template functions when appropriate - * - * @param {Mixed} - * abstract syntax tree (top node or subnode) - * @param {Array} - * replacements for $1, $2, ... $n + * + * @param {Mixed} abstract syntax tree (top node or subnode) + * @param {Array} replacements for $1, $2, ... $n * @return {Mixed} single-string node or array of nodes suitable for - * jQuery appending + * jQuery appending. */ emit: function ( node, replacements ) { - var ret = null; - var that = this; + var ret, subnodes, operation, + that = this; switch (typeof node) { case 'string': @@ -884,10 +921,10 @@ break; case 'object': // node is an array of nodes - var subnodes = $.map( node.slice( 1 ), function ( n ) { + subnodes = $.map( node.slice( 1 ), function ( n ) { return that.emit( n, replacements ); } ); - var operation = node[0].toLowerCase(); + operation = node[0].toLowerCase(); if ( typeof that[operation] === 'function' ) { ret = that[operation]( subnodes, replacements ); } else { @@ -906,6 +943,7 @@ default: throw new Error( 'unexpected type in AST: ' + typeof node ); } + return ret; }, @@ -914,13 +952,12 @@ * here are single nodes Must return a single node to parents -- a * jQuery with synthetic span However, unwrap any other synthetic spans * in our children and pass them upwards - * - * @param {Array} - * nodes - mixed, some single nodes, some arrays of nodes + * + * @param {Array} nodes Mixed, some single nodes, some arrays of nodes. * @return String */ concat: function ( nodes ) { - var result = ""; + var result = ''; $.each( nodes, function ( i, node ) { // strings, integers, anything else result += node; @@ -935,10 +972,9 @@ * parameter is not found return the same string (e.g. "$99" -> * parameter 98 -> not found -> return "$99" ) TODO throw error if * nodes.length > 1 ? - * - * @param {Array} - * of one element, integer, n >= 0 - * @return {String} replacement + * + * @param {Array} nodes One element, integer, n >= 0 + * @return {string} replacement */ replace: function ( nodes, replacements ) { var index = parseInt( nodes[0], 10 ); @@ -957,44 +993,41 @@ * be a non-integer (for instance, a string representing an Arabic * number). So convert it back with the current language's * convertNumber. - * - * @param {Array} - * of nodes, [ {String|Number}, {String}, {String} ... ] + * + * @param {Array} nodes List [ {String|Number}, {String}, {String} ... ] * @return {String} selected pluralized form according to current - * language + * language. */ plural: function ( nodes ) { - var count = parseFloat( this.language.convertNumber( nodes[0], 10 ) ); - var forms = nodes.slice( 1 ); + var count = parseFloat( this.language.convertNumber( nodes[0], 10 ) ), + forms = nodes.slice( 1 ); return forms.length ? this.language.convertPlural( count, forms ) : ''; }, /** * Transform parsed structure into gender Usage * {{gender:gender|masculine|feminine|neutral}}. - * - * @param {Array} - * of nodes, [ {String}, {String}, {String} , {String} ] + * + * @param {Array} nodes List [ {String}, {String}, {String} , {String} ] * @return {String} selected gender form according to current language */ gender: function ( nodes ) { - var gender = nodes[0]; - var forms = nodes.slice( 1 ); + var gender = nodes[0], + forms = nodes.slice( 1 ); return this.language.gender( gender, forms ); }, /** * Transform parsed structure into grammar conversion. Invoked by * putting {{grammar:form|word}} in a message - * - * @param {Array} - * of nodes [{Grammar case eg: genitive}, {String word}] + * + * @param {Array} nodes List [{Grammar case eg: genitive}, {String word}] * @return {String} selected grammatical form according to current - * language + * language. */ grammar: function ( nodes ) { - var form = nodes[0]; - var word = nodes[1]; + var form = nodes[0], + word = nodes[1]; return word && form && this.language.convertGrammar( word, form ); } }; @@ -1002,9 +1035,10 @@ $.extend( $.i18n.parser.emitter, new MessageParserEmitter() ); }( jQuery ) ); -/* global pluralRuleParser */ +/*global pluralRuleParser */ ( function ( $ ) { - "use strict"; + 'use strict'; + var language = { // CLDR plural rules generated using @@ -1012,506 +1046,506 @@ // and compressed pluralRules: { gv: { - one: "n mod 10 in 1..2 or n mod 20 is 0" + one: 'n mod 10 in 1..2 or n mod 20 is 0' }, gu: { - one: "n is 1" + one: 'n is 1' }, rof: { - one: "n is 1" + one: 'n is 1' }, ga: { - few: "n in 3..6", - many: "n in 7..10", - two: "n is 2", - one: "n is 1" + few: 'n in 3..6', + many: 'n in 7..10', + two: 'n is 2', + one: 'n is 1' }, gl: { - one: "n is 1" + one: 'n is 1' }, lg: { - one: "n is 1" + one: 'n is 1' }, lb: { - one: "n is 1" + one: 'n is 1' }, xog: { - one: "n is 1" + one: 'n is 1' }, ln: { - one: "n in 0..1" + one: 'n in 0..1' }, - lo: "", + lo: '', brx: { - one: "n is 1" + one: 'n is 1' }, - tr: "", + tr: '', ts: { - one: "n is 1" + one: 'n is 1' }, tn: { - one: "n is 1" + one: 'n is 1' }, - to: "", + to: '', lt: { - few: "n mod 10 in 2..9 and n mod 100 not in 11..19", - one: "n mod 10 is 1 and n mod 100 not in 11..19" + few: 'n mod 10 in 2..9 and n mod 100 not in 11..19', + one: 'n mod 10 is 1 and n mod 100 not in 11..19' }, tk: { - one: "n is 1" + one: 'n is 1' }, - th: "", + th: '', ksb: { - one: "n is 1" + one: 'n is 1' }, te: { - one: "n is 1" + one: 'n is 1' }, ksh: { - zero: "n is 0", - one: "n is 1" + zero: 'n is 0', + one: 'n is 1' }, fil: { - one: "n in 0..1" + one: 'n in 0..1' }, haw: { - one: "n is 1" + one: 'n is 1' }, kcg: { - one: "n is 1" + one: 'n is 1' }, ssy: { - one: "n is 1" + one: 'n is 1' }, - yo: "", + yo: '', de: { - one: "n is 1" + one: 'n is 1' }, - ko: "", + ko: '', da: { - one: "n is 1" + one: 'n is 1' }, - dz: "", + dz: '', dv: { - one: "n is 1" + one: 'n is 1' }, guw: { - one: "n in 0..1" + one: 'n in 0..1' }, shi: { - few: "n in 2..10", - one: "n within 0..1" + few: 'n in 2..10', + one: 'n within 0..1' }, el: { - one: "n is 1" + one: 'n is 1' }, eo: { - one: "n is 1" + one: 'n is 1' }, en: { - one: "n is 1" + one: 'n is 1' }, - ses: "", + ses: '', teo: { - one: "n is 1" + one: 'n is 1' }, ee: { - one: "n is 1" + one: 'n is 1' }, - kde: "", + kde: '', fr: { - one: "n within 0..2 and n is not 2" + one: 'n within 0..2 and n is not 2' }, eu: { - one: "n is 1" + one: 'n is 1' }, et: { - one: "n is 1" + one: 'n is 1' }, es: { - one: "n is 1" + one: 'n is 1' }, seh: { - one: "n is 1" + one: 'n is 1' }, ru: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14", - one: "n mod 10 is 1 and n mod 100 is not 11" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, kl: { - one: "n is 1" + one: 'n is 1' }, sms: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, smn: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, smj: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, smi: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, fy: { - one: "n is 1" + one: 'n is 1' }, rm: { - one: "n is 1" + one: 'n is 1' }, ro: { - few: "n is 0 OR n is not 1 AND n mod 100 in 1..19", - one: "n is 1" + few: 'n is 0 OR n is not 1 AND n mod 100 in 1..19', + one: 'n is 1' }, bn: { - one: "n is 1" + one: 'n is 1' }, sma: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, be: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14", - one: "n mod 10 is 1 and n mod 100 is not 11" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, bg: { - one: "n is 1" + one: 'n is 1' }, - ms: "", + ms: '', wa: { - one: "n in 0..1" + one: 'n in 0..1' }, ps: { - one: "n is 1" + one: 'n is 1' }, - wo: "", - bm: "", - jv: "", - bo: "", + wo: '', + bm: '', + jv: '', + bo: '', bh: { - one: "n in 0..1" + one: 'n in 0..1' }, - kea: "", + kea: '', asa: { - one: "n is 1" + one: 'n is 1' }, cgg: { - one: "n is 1" + one: 'n is 1' }, br: { - few: "n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99", - many: "n mod 1000000 is 0 and n is not 0", - two: "n mod 10 is 2 and n mod 100 not in 12,72,92", - one: "n mod 10 is 1 and n mod 100 not in 11,71,91" + few: 'n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99', + many: 'n mod 1000000 is 0 and n is not 0', + two: 'n mod 10 is 2 and n mod 100 not in 12,72,92', + one: 'n mod 10 is 1 and n mod 100 not in 11,71,91' }, bs: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14", - one: "n mod 10 is 1 and n mod 100 is not 11" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, - ja: "", + ja: '', om: { - one: "n is 1" + one: 'n is 1' }, - fa: "", + fa: '', vun: { - one: "n is 1" + one: 'n is 1' }, or: { - one: "n is 1" + one: 'n is 1' }, xh: { - one: "n is 1" + one: 'n is 1' }, nso: { - one: "n in 0..1" + one: 'n in 0..1' }, ca: { - one: "n is 1" + one: 'n is 1' }, cy: { - few: "n is 3", - zero: "n is 0", - many: "n is 6", - two: "n is 2", - one: "n is 1" + few: 'n is 3', + zero: 'n is 0', + many: 'n is 6', + two: 'n is 2', + one: 'n is 1' }, cs: { - few: "n in 2..4", - one: "n is 1" + few: 'n in 2..4', + one: 'n is 1' }, - zh: "", + zh: '', lv: { - zero: "n is 0", - one: "n mod 10 is 1 and n mod 100 is not 11" + zero: 'n is 0', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, pt: { - one: "n is 1" + one: 'n is 1' }, wae: { - one: "n is 1" + one: 'n is 1' }, tl: { - one: "n in 0..1" + one: 'n in 0..1' }, chr: { - one: "n is 1" + one: 'n is 1' }, pa: { - one: "n is 1" + one: 'n is 1' }, ak: { - one: "n in 0..1" + one: 'n in 0..1' }, pl: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n is not 1 and n mod 10 in 0..1 or n mod 10 in 5..9 or n mod 100 in 12..14", - one: "n is 1" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n is not 1 and n mod 10 in 0..1 or n mod 10 in 5..9 or n mod 100 in 12..14', + one: 'n is 1' }, hr: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14", - one: "n mod 10 is 1 and n mod 100 is not 11" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, am: { - one: "n in 0..1" + one: 'n in 0..1' }, ti: { - one: "n in 0..1" + one: 'n in 0..1' }, - hu: "", + hu: '', hi: { - one: "n in 0..1" + one: 'n in 0..1' }, jmc: { - one: "n is 1" + one: 'n is 1' }, ha: { - one: "n is 1" + one: 'n is 1' }, he: { - one: "n is 1" + one: 'n is 1' }, mg: { - one: "n in 0..1" + one: 'n in 0..1' }, fur: { - one: "n is 1" + one: 'n is 1' }, bem: { - one: "n is 1" + one: 'n is 1' }, ml: { - one: "n is 1" + one: 'n is 1' }, mo: { - few: "n is 0 OR n is not 1 AND n mod 100 in 1..19", - one: "n is 1" + few: 'n is 0 OR n is not 1 AND n mod 100 in 1..19', + one: 'n is 1' }, mn: { - one: "n is 1" + one: 'n is 1' }, mk: { - one: "n mod 10 is 1 and n is not 11" + one: 'n mod 10 is 1 and n is not 11' }, ur: { - one: "n is 1" + one: 'n is 1' }, bez: { - one: "n is 1" + one: 'n is 1' }, mt: { - few: "n is 0 or n mod 100 in 2..10", - many: "n mod 100 in 11..19", - one: "n is 1" + few: 'n is 0 or n mod 100 in 2..10', + many: 'n mod 100 in 11..19', + one: 'n is 1' }, uk: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14", - one: "n mod 10 is 1 and n mod 100 is not 11" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, mr: { - one: "n is 1" + one: 'n is 1' }, ta: { - one: "n is 1" + one: 'n is 1' }, - my: "", - sah: "", + my: '', + sah: '', ve: { - one: "n is 1" + one: 'n is 1' }, af: { - one: "n is 1" + one: 'n is 1' }, - vi: "", + vi: '', is: { - one: "n is 1" + one: 'n is 1' }, iu: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, it: { - one: "n is 1" + one: 'n is 1' }, - kn: "", - ii: "", + kn: '', + ii: '', ar: { - few: "n mod 100 in 3..10", - zero: "n is 0", - many: "n mod 100 in 11..99", - two: "n is 2", - one: "n is 1" + few: 'n mod 100 in 3..10', + zero: 'n is 0', + many: 'n mod 100 in 11..99', + two: 'n is 2', + one: 'n is 1' }, zu: { - one: "n is 1" + one: 'n is 1' }, saq: { - one: "n is 1" + one: 'n is 1' }, - az: "", + az: '', tzm: { - one: "n in 0..1 or n in 11..99" + one: 'n in 0..1 or n in 11..99' }, - id: "", - ig: "", + id: '', + ig: '', pap: { - one: "n is 1" + one: 'n is 1' }, nl: { - one: "n is 1" + one: 'n is 1' }, nn: { - one: "n is 1" + one: 'n is 1' }, no: { - one: "n is 1" + one: 'n is 1' }, nah: { - one: "n is 1" + one: 'n is 1' }, nd: { - one: "n is 1" + one: 'n is 1' }, ne: { - one: "n is 1" + one: 'n is 1' }, ny: { - one: "n is 1" + one: 'n is 1' }, naq: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, nyn: { - one: "n is 1" + one: 'n is 1' }, kw: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' }, nr: { - one: "n is 1" + one: 'n is 1' }, tig: { - one: "n is 1" + one: 'n is 1' }, kab: { - one: "n within 0..2 and n is not 2" + one: 'n within 0..2 and n is not 2' }, mas: { - one: "n is 1" + one: 'n is 1' }, rwk: { - one: "n is 1" + one: 'n is 1' }, kaj: { - one: "n is 1" + one: 'n is 1' }, lag: { - zero: "n is 0", - one: "n within 0..2 and n is not 0 and n is not 2" + zero: 'n is 0', + one: 'n within 0..2 and n is not 0 and n is not 2' }, syr: { - one: "n is 1" + one: 'n is 1' }, kk: { - one: "n is 1" + one: 'n is 1' }, ff: { - one: "n within 0..2 and n is not 2" + one: 'n within 0..2 and n is not 2' }, fi: { - one: "n is 1" + one: 'n is 1' }, fo: { - one: "n is 1" + one: 'n is 1' }, - ka: "", + ka: '', gsw: { - one: "n is 1" + one: 'n is 1' }, ckb: { - one: "n is 1" + one: 'n is 1' }, ss: { - one: "n is 1" + one: 'n is 1' }, sr: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14", - one: "n mod 10 is 1 and n mod 100 is not 11" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, sq: { - one: "n is 1" + one: 'n is 1' }, sw: { - one: "n is 1" + one: 'n is 1' }, sv: { - one: "n is 1" + one: 'n is 1' }, - km: "", + km: '', st: { - one: "n is 1" + one: 'n is 1' }, sk: { - few: "n in 2..4", - one: "n is 1" + few: 'n in 2..4', + one: 'n is 1' }, sh: { - few: "n mod 10 in 2..4 and n mod 100 not in 12..14", - many: "n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14", - one: "n mod 10 is 1 and n mod 100 is not 11" + few: 'n mod 10 in 2..4 and n mod 100 not in 12..14', + many: 'n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14', + one: 'n mod 10 is 1 and n mod 100 is not 11' }, so: { - one: "n is 1" + one: 'n is 1' }, sn: { - one: "n is 1" + one: 'n is 1' }, ku: { - one: "n is 1" + one: 'n is 1' }, sl: { - few: "n mod 100 in 3..4", - two: "n mod 100 is 2", - one: "n mod 100 is 1" + few: 'n mod 100 in 3..4', + two: 'n mod 100 is 2', + one: 'n mod 100 is 1' }, - sg: "", + sg: '', nb: { - one: "n is 1" + one: 'n is 1' }, se: { - two: "n is 2", - one: "n is 1" + two: 'n is 2', + one: 'n is 1' } }, @@ -1525,11 +1559,12 @@ * @return string Correct form for quantifier in this language */ convertPlural: function ( count, forms ) { - var pluralFormIndex = 0; + var pluralRules, + pluralFormIndex = 0; if ( !forms || forms.length === 0 ) { return ''; } - var pluralRules = this.pluralRules[$.i18n().locale]; + pluralRules = this.pluralRules[$.i18n().locale]; if ( !pluralRules ) { // default fallback. return ( count === 1 ) ? forms[0] : forms[1]; @@ -1547,9 +1582,10 @@ * @return plural form index */ getPluralForm: function ( number, pluralRules ) { - var pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ]; - var pluralFormIndex = 0; - for ( var i = 0; i < pluralForms.length; i++) { + var i, + pluralForms = [ 'zero', 'one', 'two', 'few', 'many', 'other' ], + pluralFormIndex = 0; + for ( i = 0; i < pluralForms.length; i++) { if ( pluralRules[pluralForms[i]] ) { if ( pluralRuleParser( pluralRules[pluralForms[i]], number ) ) { return pluralFormIndex; @@ -1569,24 +1605,28 @@ * integer Convert the return value to an integer */ 'convertNumber': function ( num, integer ) { + var tmp, item, i, + transformTable, numberString, convertedNumber; + // Set the target Transform table: - var transformTable = this.digitTransformTable( $.i18n().locale ), numberString = '' - + num, convertedNumber = ''; + transformTable = this.digitTransformTable( $.i18n().locale ); + numberString = '' + num; + convertedNumber = ''; if ( !transformTable ) { return num; } - // Check if the "restore" to Latin number flag is set: + // Check if the restore to Latin number flag is set: if ( integer ) { if ( parseFloat( num, 10 ) === num ) { return num; } - var tmp = []; - for ( var item in transformTable) { + tmp = []; + for ( item in transformTable) { tmp[transformTable[item]] = item; } transformTable = tmp; } - for ( var i = 0; i < numberString.length; i++) { + for ( i = 0; i < numberString.length; i++) { if ( transformTable[numberString[i]] ) { convertedNumber += transformTable[numberString[i]]; } else { @@ -1644,29 +1684,30 @@ * Get the digit transform table for the given language * See http://cldr.unicode.org/translation/numbering-systems * @param language - * @returns Array of digits in the passed language representation + * @returns {Array|false} List of digits in the passed language + * representation, or boolean false if there is no information. */ digitTransformTable: function ( language ) { var tables = { - ar: "۰۱۲۳۴۵۶۷۸۹", - ml: "൦൧൨൩൪൫൬൭൮൯", - kn: "೦೧೨೩೪೫೬೭೮೯", - lo: "໐໑໒໓໔໕໖໗໘໙", - or: "୦୧୨୩୪୫୬୭୮୯", - kh: "០១២៣៤៥៦៧៨៩", - pa: "੦੧੨੩੪੫੬੭੮੯", - gu: "૦૧૨૩૪૫૬૭૮૯", - hi: "०१२३४५६७८९", - my: "၀၁၂၃၄၅၆၇၈၉", - ta: "௦௧௨௩௪௫௬௭௮௯", - te: "౦౧౨౩౪౫౬౭౮౯", - th: "๐๑๒๓๔๕๖๗๘๙", //FIXME use iso 639 codes - bo: "༠༡༢༣༤༥༦༧༨༩" //FIXME use iso 639 codes + ar: '۰۱۲۳۴۵۶۷۸۹', + ml: '൦൧൨൩൪൫൬൭൮൯', + kn: '೦೧೨೩೪೫೬೭೮೯', + lo: '໐໑໒໓໔໕໖໗໘໙', + or: '୦୧୨୩୪୫୬୭୮୯', + kh: '០១២៣៤៥៦៧៨៩', + pa: '੦੧੨੩੪੫੬੭੮੯', + gu: '૦૧૨૩૪૫૬૭૮૯', + hi: '०१२३४५६७८९', + my: '၀၁၂၃၄၅၆၇၈၉', + ta: '௦௧௨௩௪௫௬௭௮௯', + te: '౦౧౨౩౪౫౬౭౮౯', + th: '๐๑๒๓๔๕๖๗๘๙', //FIXME use iso 639 codes + bo: '༠༡༢༣༤༥༦༧༨༩' //FIXME use iso 639 codes }; if ( !tables[language] ) { - return null; + return false; } - return tables[language].split( "" ); + return tables[language].split( '' ); } }; @@ -1680,8 +1721,9 @@ * Bosnian (bosanski) language functions */ ( function ( $ ) { - "use strict"; - var bosanski = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.bs = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { switch (form) { case 'instrumental': // instrumental @@ -1694,33 +1736,29 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'bs': bosanski - } ); + }( jQuery ) ); /** * Lower Sorbian (Dolnoserbski) language functions */ - ( function ( $ ) { - "use strict"; - var dsb = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.dsb = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { - switch (form) { - case 'instrumental': // instrumental - word = 'z ' + word; - break; - case 'lokatiw': // lokatiw - word = 'wo ' + word; - break; + switch ( form ) { + case 'instrumental': // instrumental + word = 'z ' + word; + break; + case 'lokatiw': // lokatiw + word = 'wo ' + word; + break; } return word; } } ); - $.extend( $.i18n.languages, { - 'dsb': dsb - } ); + }( jQuery ) ); /** @@ -1730,12 +1768,13 @@ */ ( function ( $ ) { - "use strict"; - var finnish = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.fi = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { // vowel harmony flag - var aou = word.match( /[aou][^äöy]*$/i ); - var origWord = word; + var aou = word.match( /[aou][^äöy]*$/i ), + origWord = word; if ( word.match( /wiki$/i ) ) { aou = false; } @@ -1768,18 +1807,16 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'fi': finnish - } ); + }( jQuery ) ); /** * Irish (Gaeilge) language functions */ - ( function ( $ ) { - "use strict"; - var ga = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.ga = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { if ( form === 'ainmlae' ) { switch (word) { @@ -1809,52 +1846,48 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'ga': ga - } ); + }( jQuery ) ); /** * Hebrew (עברית) language functions */ - ( function ( $ ) { - "use strict"; - var hebrew = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.he = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { switch (form) { case 'prefixed': case 'תחילית': // the same word in Hebrew // Duplicate prefixed "Waw", but only if it's not already double - if ( word.substr( 0, 1 ) === "ו" && word.substr( 0, 2 ) !== "וו" ) { - word = "ו" + word; + if ( word.substr( 0, 1 ) === 'ו' && word.substr( 0, 2 ) !== 'וו' ) { + word = 'ו' + word; } // Remove the "He" if prefixed - if ( word.substr( 0, 1 ) === "ה" ) { + if ( word.substr( 0, 1 ) === 'ה' ) { word = word.substr( 1, word.length ); } // Add a hyphen (maqaf) before numbers and non-Hebrew letters - if ( word.substr( 0, 1 ) < "א" || word.substr( 0, 1 ) > "ת" ) { - word = "־" + word; + if ( word.substr( 0, 1 ) < 'א' || word.substr( 0, 1 ) > 'ת' ) { + word = '־' + word; } } return word; } } ); - $.extend( $.i18n.languages, { - 'he': hebrew - } ); + }( jQuery ) ); /** * Upper Sorbian (Hornjoserbsce) language functions */ - ( function ( $ ) { - "use strict"; - var hsb = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.hsb = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { switch (form) { case 'instrumental': // instrumental @@ -1867,9 +1900,7 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'hsb': hsb - } ); + }( jQuery ) ); /** @@ -1877,10 +1908,10 @@ * * @author Santhosh Thottingal */ - ( function ( $ ) { - "use strict"; - var hu = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.hu = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { switch (form) { case 'rol': @@ -1896,9 +1927,7 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'hu': hu - } ); + }( jQuery ) ); /** @@ -1906,8 +1935,9 @@ */ ( function ( $ ) { - "use strict"; - var hy = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.hy = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { if ( form === 'genitive' ) {// սեռական հոլով if ( word.substr( -1 ) === 'ա' ) { @@ -1923,9 +1953,7 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'hy': hy - } ); + }( jQuery ) ); /** @@ -1935,8 +1963,9 @@ */ ( function ( $ ) { - "use strict"; - var la = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.la = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { switch (form) { case 'genitive': @@ -1979,9 +2008,7 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'la': la - } ); + }( jQuery ) ); /** @@ -1991,75 +2018,73 @@ */ ( function ( $ ) { - "use strict"; - var os = $.extend( {}, $.i18n.languages['default'], - { - convertGrammar: function ( word, form ) { - // Ending for allative case - var end_allative = 'мæ'; - // Variable for 'j' beetwen vowels - var jot = ''; - // Variable for "-" for not Ossetic words - var hyphen = ''; - // Variable for ending - var ending = ''; - // Checking if the $word is in plural form - if ( word.match( /тæ$/i ) ) { - word = word.substring( 0, word.length - 1 ); - end_allative = 'æм'; - } - // Works if word is in singular form. - // Checking if word ends on one of the vowels: е, ё, и, о, ы, э, ю, - // я. - else if ( word.match( /[аæеёиоыэюя]$/i ) ) { - jot = 'й'; - } - // Checking if word ends on 'у'. 'У' can be either consonant 'W' or - // vowel 'U' in cyrillic Ossetic. - // Examples: {{grammar:genitive|аунеу}} = аунеуы, - // {{grammar:genitive|лæппу}} = лæппуйы. - else if ( word.match( /у$/i ) ) { - if ( !word.substring( word.length - 2, word.length - 1 ).match( - /[аæеёиоыэюя]$/i ) ) { - jot = 'й'; - } - } else if ( !word.match( /[бвгджзйклмнопрстфхцчшщьъ]$/i ) ) { - hyphen = '-'; - } + 'use strict'; - switch (form) { - case 'genitive': - ending = hyphen + jot + 'ы'; - break; - case 'dative': - ending = hyphen + jot + 'æн'; - break; - case 'allative': - ending = hyphen + end_allative; - break; - case 'ablative': - if ( jot === 'й' ) { - ending = hyphen + jot + 'æ'; - } else { - ending = hyphen + jot + 'æй'; - } - break; - case 'superessive': - ending = hyphen + jot + 'ыл'; - break; - case 'equative': - ending = hyphen + jot + 'ау'; - break; - case 'comitative': - ending = hyphen + 'имæ'; - break; - } - return word + ending; + $.i18n.languages.os = $.extend( {}, $.i18n.languages['default'], { + convertGrammar: function ( word, form ) { + // Ending for allative case + var endAllative = 'мæ'; + // Variable for 'j' beetwen vowels + var jot = ''; + // Variable for "-" for not Ossetic words + var hyphen = ''; + // Variable for ending + var ending = ''; + // Checking if the $word is in plural form + if ( word.match( /тæ$/i ) ) { + word = word.substring( 0, word.length - 1 ); + endAllative = 'æм'; + } + // Works if word is in singular form. + // Checking if word ends on one of the vowels: е, ё, и, о, ы, э, ю, + // я. + else if ( word.match( /[аæеёиоыэюя]$/i ) ) { + jot = 'й'; + } + // Checking if word ends on 'у'. 'У' can be either consonant 'W' or + // vowel 'U' in cyrillic Ossetic. + // Examples: {{grammar:genitive|аунеу}} = аунеуы, + // {{grammar:genitive|лæппу}} = лæппуйы. + else if ( word.match( /у$/i ) ) { + if ( !word.substring( word.length - 2, word.length - 1 ).match( + /[аæеёиоыэюя]$/i ) ) { + jot = 'й'; } - } ); - $.extend( $.i18n.languages, { - 'os': os + } else if ( !word.match( /[бвгджзйклмнопрстфхцчшщьъ]$/i ) ) { + hyphen = '-'; + } + + switch (form) { + case 'genitive': + ending = hyphen + jot + 'ы'; + break; + case 'dative': + ending = hyphen + jot + 'æн'; + break; + case 'allative': + ending = hyphen + endAllative; + break; + case 'ablative': + if ( jot === 'й' ) { + ending = hyphen + jot + 'æ'; + } else { + ending = hyphen + jot + 'æй'; + } + break; + case 'superessive': + ending = hyphen + jot + 'ыл'; + break; + case 'equative': + ending = hyphen + jot + 'ау'; + break; + case 'comitative': + ending = hyphen + 'имæ'; + break; + } + return word + ending; + } } ); + }( jQuery ) ); /** @@ -2067,12 +2092,15 @@ */ ( function ( $ ) { - "use strict"; - var ru = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.ru = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { if ( form === 'genitive' ) { // родительный падеж - if ( ( word.substr( word.length - 4 ) === 'вики' ) - || ( word.substr( word.length - 4 ) === 'Вики' ) ) { + if ( ( word.substr( word.length - 4 ) === 'вики' ) || + ( word.substr( word.length - 4 ) === 'Вики' ) + ) { + // ... } else if ( word.substr( word.length - 1 ) === 'ь' ) { word = word.substr( 0, word.length - 1 ) + 'я'; } else if ( word.substr( word.length - 2 ) === 'ия' ) { @@ -2090,46 +2118,50 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'ru': ru - } ); + }( jQuery ) ); + /** * Slovenian (Slovenščina) language functions */ ( function ( $ ) { - "use strict"; - var sl = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.sl = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { switch (form) { - case 'mestnik': // locative - word = 'o ' + word; - break; - case 'orodnik': // instrumental - word = 'z ' + word; - break; + // locative + case 'mestnik': + word = 'o ' + word; + break; + // instrumental + case 'orodnik': + word = 'z ' + word; + break; } return word; } } ); - $.extend( $.i18n.languages, { - 'sl': sl - } ); + }( jQuery ) ); + /** * Ukrainian (Українська) language functions */ ( function ( $ ) { - "use strict"; - var uk = $.extend( {}, $.i18n.languages['default'], { + 'use strict'; + + $.i18n.languages.uk = $.extend( {}, $.i18n.languages['default'], { convertGrammar: function ( word, form ) { switch (form) { case 'genitive': // родовий відмінок - if ( ( word.substr( word.length - 4 ) === 'вікі' ) - || ( word.substr( word.length - 4 ) === 'Вікі' ) ) { + if ( ( word.substr( word.length - 4 ) === 'вікі' ) || + ( word.substr( word.length - 4 ) === 'Вікі' ) + ) { + // ... } else if ( word.substr( word.length - 1 ) === 'ь' ) { word = word.substr( 0, word.length - 1 ) + 'я'; } else if ( word.substr( word.length - 2 ) === 'ія' ) { @@ -2145,8 +2177,10 @@ } break; case 'accusative': // знахідний відмінок - if ( ( word.substr( word.length - 4 ) === 'вікі' ) - || ( word.substr( word.length - 4 ) === 'Вікі' ) ) { + if ( ( word.substr( word.length - 4 ) === 'вікі' ) || + ( word.substr( word.length - 4 ) === 'Вікі' ) + ) { + // ... } else if ( word.substr( word.length - 2 ) === 'ія' ) { word = word.substr( 0, word.length - 2 ) + 'ію'; } @@ -2155,10 +2189,9 @@ return word; } } ); - $.extend( $.i18n.languages, { - 'uk': uk - } ); + }( jQuery ) ); + /** * cldrpluralparser.js * A parser engine for CLDR plural rules.