resources: Upgrade jquery.i18n from 1.0.4 to 1.0.5
[lhc/web/wiklou.git] / resources / lib / jquery.i18n / src / jquery.i18n.js
index 9236e4e..ef2fcc2 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*!
  * jQuery Internationalization library
  *
  * Copyright (C) 2012 Santhosh Thottingal
@@ -16,7 +16,7 @@
 ( function ( $ ) {
        'use strict';
 
-       var nav, I18N,
+       var I18N,
                slice = Array.prototype.slice;
        /**
         * @constructor
                this.locale = this.options.locale;
                this.messageStore = this.options.messageStore;
                this.languages = {};
-
-               this.init();
        };
 
        I18N.prototype = {
                /**
-                * Initialize by loading locales and setting up
-                * String.prototype.toLocaleString and String.locale.
+                * Localize a given messageKey to a locale.
+                * @param {String} messageKey
+                * @return {String} Localized message
                 */
-               init: function () {
-                       var i18n = this;
-
-                       // Set locale of String environment
-                       String.locale = i18n.locale;
-
-                       // Override String.localeString method
-                       String.prototype.toLocaleString = function () {
-                               var localeParts, localePartIndex, value, locale, fallbackIndex,
-                                       tryingLocale, message;
-
-                               value = this.valueOf();
-                               locale = i18n.locale;
-                               fallbackIndex = 0;
+               localize: function ( messageKey ) {
+                       var localeParts, localePartIndex, locale, fallbackIndex,
+                               tryingLocale, message;
 
-                               while ( locale ) {
-                                       // Iterate through locales starting at most-specific until
-                                       // localization is found. As in fi-Latn-FI, fi-Latn and fi.
-                                       localeParts = locale.split( '-' );
-                                       localePartIndex = localeParts.length;
+                       locale = this.locale;
+                       fallbackIndex = 0;
 
-                                       do {
-                                               tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' );
-                                               message = i18n.messageStore.get( tryingLocale, value );
+                       while ( locale ) {
+                               // Iterate through locales starting at most-specific until
+                               // localization is found. As in fi-Latn-FI, fi-Latn and fi.
+                               localeParts = locale.split( '-' );
+                               localePartIndex = localeParts.length;
 
-                                               if ( message ) {
-                                                       return message;
-                                               }
+                               do {
+                                       tryingLocale = localeParts.slice( 0, localePartIndex ).join( '-' );
+                                       message = this.messageStore.get( tryingLocale, messageKey );
 
-                                               localePartIndex--;
-                                       } while ( localePartIndex );
-
-                                       if ( locale === 'en' ) {
-                                               break;
+                                       if ( message ) {
+                                               return message;
                                        }
 
-                                       locale = ( $.i18n.fallbacks[i18n.locale] && $.i18n.fallbacks[i18n.locale][fallbackIndex] ) ||
-                                               i18n.options.fallbackLocale;
-                                       $.i18n.log( 'Trying fallback locale for ' + i18n.locale + ': ' + locale );
+                                       localePartIndex--;
+                               } while ( localePartIndex );
 
-                                       fallbackIndex++;
+                               if ( locale === 'en' ) {
+                                       break;
                                }
 
-                               // key not found
-                               return '';
-                       };
+                               locale = ( $.i18n.fallbacks[ this.locale ] &&
+                                               $.i18n.fallbacks[ this.locale ][ fallbackIndex ] ) ||
+                                               this.options.fallbackLocale;
+                               $.i18n.log( 'Trying fallback locale for ' + this.locale + ': ' + locale + ' (' + messageKey + ')' );
+
+                               fallbackIndex++;
+                       }
+
+                       // key not found
+                       return '';
                },
 
                /*
                 * If the data argument is null/undefined/false,
                 * all cached messages for the i18n instance will get reset.
                 *
-                * @param {String|Object} source
-                * @param {String} locale Language tag
-                * @returns {jQuery.Promise}
+                * @param {string|Object} source
+                * @param {string} locale Language tag
+                * @return {jQuery.Promise}
                 */
                load: function ( source, locale ) {
                        var fallbackLocales, locIndex, fallbackLocale, sourceMap = {};
                                source = 'i18n/' + $.i18n().locale + '.json';
                                locale = $.i18n().locale;
                        }
-                       if ( typeof source === 'string' &&
-                               source.split( '.' ).pop() !== 'json'
+                       if ( typeof source === 'string' &&
+                               // source extension should be json, but can have query params after that.
+                               source.split( '?' )[ 0 ].split( '.' ).pop() !== 'json'
                        ) {
-                               // Load specified locale then check for fallbacks when directory is specified in load()
-                               sourceMap[locale] = source + '/' + locale + '.json';
-                               fallbackLocales = ( $.i18n.fallbacks[locale] || [] )
+                               // Load specified locale then check for fallbacks when directory is
+                               // specified in load()
+                               sourceMap[ locale ] = source + '/' + locale + '.json';
+                               fallbackLocales = ( $.i18n.fallbacks[ locale ] || [] )
                                        .concat( this.options.fallbackLocale );
-                               for ( locIndex in fallbackLocales ) {
-                                       fallbackLocale = fallbackLocales[locIndex];
-                                       sourceMap[fallbackLocale] = source + '/' + fallbackLocale + '.json';
+                               for ( locIndex = 0; locIndex < fallbackLocales.length; locIndex++ ) {
+                                       fallbackLocale = fallbackLocales[ locIndex ];
+                                       sourceMap[ fallbackLocale ] = source + '/' + fallbackLocale + '.json';
                                }
                                return this.load( sourceMap );
                        } else {
                 * @return {string}
                 */
                parse: function ( key, parameters ) {
-                       var message = key.toLocaleString();
+                       var message = this.localize( key );
                        // 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'];
+                       this.parser.language = $.i18n.languages[ $.i18n().locale ] || $.i18n.languages[ 'default' ];
                        if ( message === '' ) {
                                message = key;
                        }
                // 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;
+                       i18n.locale = options.locale;
                }
 
                if ( !i18n ) {
                        i18n = new I18N();
                        $.data( document, 'i18n', i18n );
                }
-               String.locale = i18n.locale;
+
                return this.each( function () {
                        var $this = $( this ),
-                               messageKey = $this.data( 'i18n' );
+                               messageKey = $this.data( 'i18n' ),
+                               lBracket, rBracket, type, key;
 
                        if ( messageKey ) {
-                               $this.text( i18n.parse( messageKey ) );
+                               lBracket = messageKey.indexOf( '[' );
+                               rBracket = messageKey.indexOf( ']' );
+                               if ( lBracket !== -1 && rBracket !== -1 && lBracket < rBracket ) {
+                                       type = messageKey.slice( lBracket + 1, rBracket );
+                                       key = messageKey.slice( rBracket + 1 );
+                                       if ( type === 'html' ) {
+                                               $this.html( i18n.parse( key ) );
+                                       } else {
+                                               $this.attr( type, i18n.parse( key ) );
+                                       }
+                               } else {
+                                       $this.text( i18n.parse( messageKey ) );
+                               }
                        } else {
                                $this.find( '[data-i18n]' ).i18n();
                        }
                } );
        };
 
-       String.locale = String.locale || $( 'html' ).attr( 'lang' );
+       function getDefaultLocale() {
+               var nav, locale = $( 'html' ).attr( 'lang' );
 
-       if ( !String.locale ) {
-               if ( typeof window.navigator !== undefined ) {
-                       nav = window.navigator;
-                       String.locale = nav.language || nav.userLanguage || '';
-               } else {
-                       String.locale = '';
+               if ( !locale ) {
+                       if ( typeof window.navigator !== undefined ) {
+                               nav = window.navigator;
+                               locale = nav.language || nav.userLanguage || '';
+                       } else {
+                               locale = '';
+                       }
                }
+               return locale;
        }
 
        $.i18n.languages = {};
                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;
+                               return parameters[ index ] !== undefined ? parameters[ index ] : '$' + match;
                        } );
                },
                emitter: {}
        };
        /* Static members */
        I18N.defaults = {
-               locale: String.locale,
+               locale: getDefaultLocale(),
                fallbackLocale: 'en',
                parser: $.i18n.parser,
                messageStore: $.i18n.messageStore