From 9c40252a72e850ffeccc41f5bcea966650fae007 Mon Sep 17 00:00:00 2001 From: Kartik Mistry Date: Mon, 13 Jan 2014 12:04:08 +0530 Subject: [PATCH] Update jquery.i18n from upstream Upstream: https://github.com/wikimedia/jquery.i18n Changes: * Support fallback loading when folder is passed as source to load * Do not overwrite existing messages for a locale while adding messages second time * Fix the country code case issue * Renamed jquery.i18n.messages.js to jquery.i18n.messagestore * ULS: Updated Resources.php for renaming of jquery.i18n.messages file Change-Id: I60a6e3224cb7b8ea813a8ccd7e389071b3d1244c --- Resources.php | 2 +- lib/jquery.i18n/jquery.i18n.js | 51 +- lib/jquery.i18n/jquery.i18n.language.js | 640 ++++++------------ ...essages.js => jquery.i18n.messagestore.js} | 22 +- 4 files changed, 258 insertions(+), 457 deletions(-) rename lib/jquery.i18n/{jquery.i18n.messages.js => jquery.i18n.messagestore.js} (83%) diff --git a/Resources.php b/Resources.php index 46427214..fc7d5ca9 100644 --- a/Resources.php +++ b/Resources.php @@ -169,7 +169,7 @@ $wgResourceModules['ext.uls.webfonts.mobile'] = array( $wgResourceModules['jquery.i18n'] = array( 'scripts' => array( 'lib/jquery.i18n/jquery.i18n.js', - 'lib/jquery.i18n/jquery.i18n.messages.js', + 'lib/jquery.i18n/jquery.i18n.messagestore.js', 'lib/jquery.i18n/jquery.i18n.parser.js', 'lib/jquery.i18n/jquery.i18n.emitter.js', 'lib/jquery.i18n/jquery.i18n.language.js', diff --git a/lib/jquery.i18n/jquery.i18n.js b/lib/jquery.i18n/jquery.i18n.js index fe8d7ede..461ec94b 100644 --- a/lib/jquery.i18n/jquery.i18n.js +++ b/lib/jquery.i18n/jquery.i18n.js @@ -57,7 +57,7 @@ while ( locale ) { // Iterate through locales starting at most-specific until // localization is found. As in fi-Latn-FI, fi-Latn and fi. - localeParts = locale.toLowerCase().split( '-' ); + localeParts = locale.split( '-' ); localePartIndex = localeParts.length; do { @@ -96,18 +96,40 @@ /** * General message loading API This can take a URL string for - * the json formatted messages. + * the json formatted messages. Example: * load('path/to/all_localizations.json'); * - * This can also load a localization file for a locale + * To load a localization file for a locale: + * * load('path/to/de-messages.json', 'de' ); * + * + * To load a localization file from a directory: + * + * load('path/to/i18n/directory', 'de' ); + * + * The above method has the advantage of fallback resolution. + * ie, it will automatically load the fallback locales for de. + * For most usecases, this is the recommended method. + * It is optional to have trailing slash at end. + * * A data object containing message key- message translation mappings - * can also be passed Eg: + * can also be passed. Example: * * load( { 'hello' : 'Hello' }, optionalLocale ); - * If the data argument is - * null/undefined/false, + * + * + * A source map containing key-value pair of languagename and locations + * can also be passed. Example: + * + * load( { + * 'bn': 'i18n/bn.json', + * 'he': 'i18n/he.json', + * 'en': 'i18n/en.json' + * } ) + * + * + * If the data argument is null/undefined/false, * all cached messages for the i18n instance will get reset. * * @param {String|Object} source @@ -115,7 +137,22 @@ * @returns {jQuery.Promise} */ load: function ( source, locale ) { - return this.messageStore.load( source, locale ); + var fallbackLocales, locIndex, fallbackLocale, sourceMap = {}; + + if ( typeof source === 'string' && + source.split('.').pop() !== 'json' + ) { + fallbackLocales = ( $.i18n.fallbacks[locale] || [] ) + .concat( this.options.fallbackLocale ); + for ( locIndex in fallbackLocales ) { + fallbackLocale = fallbackLocales[locIndex]; + sourceMap[fallbackLocale] = source + '/' + fallbackLocale + '.json'; + } + return this.load( sourceMap ); + } else { + return this.messageStore.load( source, locale ); + } + }, /** diff --git a/lib/jquery.i18n/jquery.i18n.language.js b/lib/jquery.i18n/jquery.i18n.language.js index 291885fc..ee6eacbc 100644 --- a/lib/jquery.i18n/jquery.i18n.language.js +++ b/lib/jquery.i18n/jquery.i18n.language.js @@ -4,513 +4,263 @@ var language = { // CLDR plural rules generated using - // http://i18ndata.appspot.com/cldr/tags/unconfirmed/supplemental/plurals?action=browse&depth=-1 - // and compressed - pluralRules: { - gv: { - one: 'n mod 10 in 1..2 or n mod 20 is 0' + // libs/CLDRPluralRuleParser/tools/PluralXML2JSON.html + 'pluralRules': { + 'ak': { + 'one': 'n = 0..1' + }, + 'am': { + 'one': 'i = 0 or n = 1' + }, + 'ar': { + 'zero': 'n = 0', + 'one': 'n = 1', + 'two': 'n = 2', + 'few': 'n % 100 = 3..10', + 'many': 'n % 100 = 11..99' }, - gu: { - one: 'n is 1' + 'be': { + 'one': 'n % 10 = 1 and n % 100 != 11', + 'few': 'n % 10 = 2..4 and n % 100 != 12..14', + 'many': 'n % 10 = 0 or n % 10 = 5..9 or n % 100 = 11..14' + }, + 'bh': { + 'one': 'n = 0..1' }, - rof: { - one: 'n is 1' + 'bn': { + 'one': 'i = 0 or n = 1' }, - ga: { - few: 'n in 3..6', - many: 'n in 7..10', - two: 'n is 2', - one: 'n is 1' + 'br': { + 'one': 'n % 10 = 1 and n % 100 != 11,71,91', + 'two': 'n % 10 = 2 and n % 100 != 12,72,92', + 'few': 'n % 10 = 3..4,9 and n % 100 != 10..19,70..79,90..99', + 'many': 'n != 0 and n % 1000000 = 0' + }, + 'bs': { + 'one': 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', + 'few': 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' + }, + 'cs': { + 'one': 'i = 1 and v = 0', + 'few': 'i = 2..4 and v = 0', + 'many': 'v != 0' }, - gl: { - one: 'n is 1' + 'cy': { + 'zero': 'n = 0', + 'one': 'n = 1', + 'two': 'n = 2', + 'few': 'n = 3', + 'many': 'n = 6' }, - lg: { - one: 'n is 1' + 'da': { + 'one': 'n = 1 or t != 0 and i = 0,1' }, - lb: { - one: 'n is 1' + 'fa': { + 'one': 'i = 0 or n = 1' }, - xog: { - one: 'n is 1' + 'ff': { + 'one': 'i = 0,1' }, - ln: { - one: 'n in 0..1' + 'fil': { + 'one': 'i = 0..1 and v = 0' }, - lo: '', - brx: { - one: 'n is 1' + 'fr': { + 'one': 'i = 0,1' }, - tr: '', - ts: { - one: 'n is 1' + 'ga': { + 'one': 'n = 1', + 'two': 'n = 2', + 'few': 'n = 3..6', + 'many': 'n = 7..10' }, - tn: { - one: 'n is 1' + 'gd': { + 'one': 'n = 1,11', + 'two': 'n = 2,12', + 'few': 'n = 3..10,13..19' }, - 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' + 'gu': { + 'one': 'i = 0 or n = 1' }, - tk: { - one: 'n is 1' + 'guw': { + 'one': 'n = 0..1' }, - th: '', - ksb: { - one: 'n is 1' + 'gv': { + 'one': 'n % 10 = 1', + 'two': 'n % 10 = 2', + 'few': 'n % 100 = 0,20,40,60' }, - te: { - one: 'n is 1' + 'he': { + 'one': 'i = 1 and v = 0', + 'two': 'i = 2 and v = 0', + 'many': 'v = 0 and n != 0..10 and n % 10 = 0' }, - ksh: { - zero: 'n is 0', - one: 'n is 1' + 'hi': { + 'one': 'i = 0 or n = 1' }, - fil: { - one: 'n in 0..1' + 'hr': { + 'one': 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', + 'few': 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' }, - haw: { - one: 'n is 1' + 'hy': { + 'one': 'i = 0,1' }, - kcg: { - one: 'n is 1' + 'is': { + 'one': 't = 0 and i % 10 = 1 and i % 100 != 11 or t != 0' }, - ssy: { - one: 'n is 1' + 'iu': { + 'one': 'n = 1', + 'two': 'n = 2' }, - yo: '', - de: { - one: 'n is 1' + 'iw': { + 'one': 'i = 1 and v = 0', + 'two': 'i = 2 and v = 0', + 'many': 'v = 0 and n != 0..10 and n % 10 = 0' }, - ko: '', - da: { - one: 'n is 1' + 'kab': { + 'one': 'i = 0,1' }, - dz: '', - dv: { - one: 'n is 1' + 'kn': { + 'one': 'i = 0 or n = 1' }, - guw: { - one: 'n in 0..1' + 'kw': { + 'one': 'n = 1', + 'two': 'n = 2' }, - shi: { - few: 'n in 2..10', - one: 'n within 0..1' + 'lag': { + 'zero': 'n = 0', + 'one': 'i = 0,1 and n != 0' }, - el: { - one: 'n is 1' + 'ln': { + 'one': 'n = 0..1' }, - eo: { - one: 'n is 1' + 'lt': { + 'one': 'n % 10 = 1 and n % 100 != 11..19', + 'few': 'n % 10 = 2..9 and n % 100 != 11..19', + 'many': 'f != 0' }, - en: { - one: 'n is 1' + 'lv': { + 'zero': 'n % 10 = 0 or n % 100 = 11..19 or v = 2 and f % 100 = 11..19', + 'one': 'n % 10 = 1 and n % 100 != 11 or v = 2 and f % 10 = 1 and f % 100 != 11 or v != 2 and f % 10 = 1' }, - ses: '', - teo: { - one: 'n is 1' + 'mg': { + 'one': 'n = 0..1' }, - ee: { - one: 'n is 1' + 'mk': { + 'one': 'v = 0 and i % 10 = 1 or f % 10 = 1' }, - kde: '', - fr: { - one: 'n within 0..2 and n is not 2' + 'mo': { + 'one': 'i = 1 and v = 0', + 'few': 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19' }, - eu: { - one: 'n is 1' + 'mr': { + 'one': 'i = 0 or n = 1' }, - et: { - one: 'n is 1' + 'mt': { + 'one': 'n = 1', + 'few': 'n = 0 or n % 100 = 2..10', + 'many': 'n % 100 = 11..19' }, - es: { - one: 'n is 1' + 'naq': { + 'one': 'n = 1', + 'two': 'n = 2' }, - seh: { - one: 'n is 1' + 'nso': { + 'one': 'n = 0..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' + 'pa': { + 'one': 'n = 0..1' }, - kl: { - one: 'n is 1' + 'pl': { + 'one': 'i = 1 and v = 0', + 'few': 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14', + 'many': 'v = 0 and i != 1 and i % 10 = 0..1 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 12..14' }, - sms: { - two: 'n is 2', - one: 'n is 1' + 'pt': { + 'one': 'i = 1 and v = 0 or i = 0 and t = 1' }, - smn: { - two: 'n is 2', - one: 'n is 1' + 'pt_PT': { + 'one': 'n = 1 and v = 0' }, - smj: { - two: 'n is 2', - one: 'n is 1' + 'ro': { + 'one': 'i = 1 and v = 0', + 'few': 'v != 0 or n = 0 or n != 1 and n % 100 = 1..19' }, - smi: { - two: 'n is 2', - one: 'n is 1' + 'ru': { + 'one': 'v = 0 and i % 10 = 1 and i % 100 != 11', + 'many': 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14' }, - fy: { - one: 'n is 1' + 'se': { + 'one': 'n = 1', + 'two': 'n = 2' }, - rm: { - one: 'n is 1' + 'sh': { + 'one': 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', + 'few': 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' }, - ro: { - few: 'n is 0 OR n is not 1 AND n mod 100 in 1..19', - one: 'n is 1' + 'shi': { + 'one': 'i = 0 or n = 1', + 'few': 'n = 2..10' }, - bn: { - one: 'n is 1' + 'si': { + 'one': 'n = 0,1 or i = 0 and f = 1' }, - sma: { - two: 'n is 2', - one: 'n is 1' + 'sk': { + 'one': 'i = 1 and v = 0', + 'few': 'i = 2..4 and v = 0', + 'many': 'v != 0' }, - 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' + 'sl': { + 'one': 'v = 0 and i % 100 = 1', + 'two': 'v = 0 and i % 100 = 2', + 'few': 'v = 0 and i % 100 = 3..4 or v != 0' }, - bg: { - one: 'n is 1' + 'sma': { + 'one': 'n = 1', + 'two': 'n = 2' }, - ms: '', - wa: { - one: 'n in 0..1' + 'smi': { + 'one': 'n = 1', + 'two': 'n = 2' }, - ps: { - one: 'n is 1' + 'smj': { + 'one': 'n = 1', + 'two': 'n = 2' }, - wo: '', - bm: '', - jv: '', - bo: '', - bh: { - one: 'n in 0..1' + 'smn': { + 'one': 'n = 1', + 'two': 'n = 2' }, - kea: '', - asa: { - one: 'n is 1' + 'sms': { + 'one': 'n = 1', + 'two': 'n = 2' }, - cgg: { - one: 'n is 1' + 'sr': { + 'one': 'v = 0 and i % 10 = 1 and i % 100 != 11 or f % 10 = 1 and f % 100 != 11', + 'few': 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14 or f % 10 = 2..4 and f % 100 != 12..14' }, - 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' + 'ti': { + 'one': 'n = 0..1' }, - 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' + 'tl': { + 'one': 'i = 0..1 and v = 0' }, - ja: '', - om: { - one: 'n is 1' + 'tzm': { + 'one': 'n = 0..1 or n = 11..99' }, - fa: '', - vun: { - one: 'n is 1' + 'uk': { + 'one': 'v = 0 and i % 10 = 1 and i % 100 != 11', + 'few': 'v = 0 and i % 10 = 2..4 and i % 100 != 12..14', + 'many': 'v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100 = 11..14' }, - or: { - one: 'n is 1' + 'wa': { + 'one': 'n = 0..1' }, - xh: { - one: 'n is 1' - }, - nso: { - one: 'n in 0..1' - }, - ca: { - 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' - }, - cs: { - few: 'n in 2..4', - one: 'n is 1' - }, - zh: '', - lv: { - zero: 'n is 0', - one: 'n mod 10 is 1 and n mod 100 is not 11' - }, - pt: { - one: 'n is 1' - }, - wae: { - one: 'n is 1' - }, - tl: { - one: 'n in 0..1' - }, - chr: { - one: 'n is 1' - }, - pa: { - one: 'n is 1' - }, - ak: { - 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' - }, - 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' - }, - am: { - one: 'n in 0..1' - }, - ti: { - one: 'n in 0..1' - }, - hu: '', - hi: { - one: 'n in 0..1' - }, - jmc: { - one: 'n is 1' - }, - ha: { - one: 'n is 1' - }, - he: { - one: 'n is 1' - }, - mg: { - one: 'n in 0..1' - }, - fur: { - one: 'n is 1' - }, - bem: { - one: 'n is 1' - }, - ml: { - 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' - }, - mn: { - one: 'n is 1' - }, - mk: { - one: 'n mod 10 is 1 and n is not 11' - }, - ur: { - one: 'n is 1' - }, - bez: { - 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' - }, - 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' - }, - mr: { - one: 'n is 1' - }, - ta: { - one: 'n is 1' - }, - my: '', - sah: '', - ve: { - one: 'n is 1' - }, - af: { - one: 'n is 1' - }, - vi: '', - is: { - one: 'n is 1' - }, - iu: { - two: 'n is 2', - one: 'n is 1' - }, - it: { - one: 'n is 1' - }, - 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' - }, - zu: { - one: 'n is 1' - }, - saq: { - one: 'n is 1' - }, - az: '', - tzm: { - one: 'n in 0..1 or n in 11..99' - }, - id: '', - ig: '', - pap: { - one: 'n is 1' - }, - nl: { - one: 'n is 1' - }, - nn: { - one: 'n is 1' - }, - no: { - one: 'n is 1' - }, - nah: { - one: 'n is 1' - }, - nd: { - one: 'n is 1' - }, - ne: { - one: 'n is 1' - }, - ny: { - one: 'n is 1' - }, - naq: { - two: 'n is 2', - one: 'n is 1' - }, - nyn: { - one: 'n is 1' - }, - kw: { - two: 'n is 2', - one: 'n is 1' - }, - nr: { - one: 'n is 1' - }, - tig: { - one: 'n is 1' - }, - kab: { - one: 'n within 0..2 and n is not 2' - }, - mas: { - one: 'n is 1' - }, - rwk: { - one: 'n is 1' - }, - kaj: { - one: 'n is 1' - }, - lag: { - zero: 'n is 0', - one: 'n within 0..2 and n is not 0 and n is not 2' - }, - syr: { - one: 'n is 1' - }, - kk: { - one: 'n is 1' - }, - ff: { - one: 'n within 0..2 and n is not 2' - }, - fi: { - one: 'n is 1' - }, - fo: { - one: 'n is 1' - }, - ka: '', - gsw: { - one: 'n is 1' - }, - ckb: { - one: 'n is 1' - }, - ss: { - 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' - }, - sq: { - one: 'n is 1' - }, - sw: { - one: 'n is 1' - }, - sv: { - one: 'n is 1' - }, - km: '', - st: { - one: 'n is 1' - }, - sk: { - 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' - }, - so: { - one: 'n is 1' - }, - sn: { - one: 'n is 1' - }, - ku: { - one: 'n is 1' - }, - sl: { - few: 'n mod 100 in 3..4', - two: 'n mod 100 is 2', - one: 'n mod 100 is 1' - }, - sg: '', - nb: { - one: 'n is 1' - }, - se: { - two: 'n is 2', - one: 'n is 1' + 'zu': { + 'one': 'i = 0 or n = 1' } }, + /** * Plural form transformations, needed for some languages. * diff --git a/lib/jquery.i18n/jquery.i18n.messages.js b/lib/jquery.i18n/jquery.i18n.messagestore.js similarity index 83% rename from lib/jquery.i18n/jquery.i18n.messages.js rename to lib/jquery.i18n/jquery.i18n.messagestore.js index 5df24abf..a8e10f9d 100644 --- a/lib/jquery.i18n/jquery.i18n.messages.js +++ b/lib/jquery.i18n/jquery.i18n.messagestore.js @@ -83,12 +83,17 @@ }, /** - * Set messages + * Set messages to the given locale. + * If locale exists, add messages to the locale. * @param locale * @param messages */ set: function( locale, messages ) { - this.messages[locale] = messages; + if ( !this.messages[locale] ) { + this.messages[locale] = messages; + } else { + this.messages[locale] = $.extend( this.messages[locale], messages ); + } }, /** @@ -102,10 +107,19 @@ } }; + function jsonMessageLoader( url ) { - return $.getJSON( url ).fail( function ( jqxhr, settings, exception ) { - $.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception ); + var deferred = $.Deferred(); + + $.getJSON( url ) + .done( deferred.resolve ) + .fail( function ( jqxhr, settings, exception ) { + $.i18n.log( 'Error in loading messages from ' + url + ' Exception: ' + exception ); + // Ignore 404 exception, because we are handling fallabacks explicitly + deferred.resolve(); } ); + + return deferred.promise(); } $.extend( $.i18n.messageStore, new MessageStore() );