[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/resources/src/mediawiki.language/ -> mediawiki.language.numbers.js (source)

   1  /*
   2   * Number-related utilities for mediawiki.language.
   3   */
   4  ( function ( mw, $ ) {
   5      /**
   6       * @class mw.language
   7       */
   8  
   9      /**
  10       * Pad a string to guarantee that it is at least `size` length by
  11       * filling with the character `ch` at either the start or end of the
  12       * string. Pads at the start, by default.
  13       *
  14       * Example: Fill the string to length 10 with '+' characters on the right.
  15       *
  16       *     pad( 'blah', 10, '+', true ); // => 'blah++++++'
  17       *
  18       * @private
  19       * @param {string} text The string to pad
  20       * @param {number} size The length to pad to
  21       * @param {string} [ch='0'] Character to pad with
  22       * @param {boolean} [end=false] Adds padding at the end if true, otherwise pads at start
  23       * @return {string}
  24       */
  25  	function pad( text, size, ch, end ) {
  26          if ( !ch ) {
  27              ch = '0';
  28          }
  29  
  30          var out = String( text ),
  31              padStr = replicate( ch, Math.ceil( ( size - out.length ) / ch.length ) );
  32  
  33          return end ? out + padStr : padStr + out;
  34      }
  35  
  36      /**
  37       * Replicate a string 'n' times.
  38       *
  39       * @private
  40       * @param {string} str The string to replicate
  41       * @param {number} num Number of times to replicate the string
  42       * @return {string}
  43       */
  44  	function replicate( str, num ) {
  45          if ( num <= 0 || !str ) {
  46              return '';
  47          }
  48  
  49          var buf = [];
  50          while ( num-- ) {
  51              buf.push( str );
  52          }
  53          return buf.join( '' );
  54      }
  55  
  56      /**
  57       * Apply numeric pattern to absolute value using options. Gives no
  58       * consideration to local customs.
  59       *
  60       * Adapted from dojo/number library with thanks
  61       * <http://dojotoolkit.org/reference-guide/1.8/dojo/number.html>
  62       *
  63       * @private
  64       * @param {number} value the number to be formatted, ignores sign
  65       * @param {string} pattern the number portion of a pattern (e.g. `#,##0.00`)
  66       * @param {Object} [options] If provided, both option keys must be present:
  67       * @param {string} options.decimal The decimal separator. Defaults to: `'.'`.
  68       * @param {string} options.group The group separator. Defaults to: `','`.
  69       * @return {string}
  70       */
  71  	function commafyNumber( value, pattern, options ) {
  72          options = options || {
  73              group: ',',
  74              decimal: '.'
  75          };
  76  
  77          if ( isNaN( value) ) {
  78              return value;
  79          }
  80  
  81          var padLength,
  82              patternDigits,
  83              index,
  84              whole,
  85              off,
  86              remainder,
  87              patternParts = pattern.split( '.' ),
  88              maxPlaces = ( patternParts[1] || [] ).length,
  89              valueParts = String( Math.abs( value ) ).split( '.' ),
  90              fractional = valueParts[1] || '',
  91              groupSize = 0,
  92              groupSize2 = 0,
  93              pieces = [];
  94  
  95          if ( patternParts[1] ) {
  96              // Pad fractional with trailing zeros
  97              padLength = ( patternParts[1] && patternParts[1].lastIndexOf( '0' ) + 1 );
  98  
  99              if ( padLength > fractional.length ) {
 100                  valueParts[1] = pad( fractional, padLength, '0', true );
 101              }
 102  
 103              // Truncate fractional
 104              if ( maxPlaces < fractional.length ) {
 105                  valueParts[1] = fractional.slice( 0, maxPlaces );
 106              }
 107          } else {
 108              if ( valueParts[1] ) {
 109                  valueParts.pop();
 110              }
 111          }
 112  
 113          // Pad whole with leading zeros
 114          patternDigits = patternParts[0].replace( ',', '' );
 115  
 116          padLength = patternDigits.indexOf( '0' );
 117  
 118          if ( padLength !== -1 ) {
 119              padLength = patternDigits.length - padLength;
 120  
 121              if ( padLength > valueParts[0].length ) {
 122                  valueParts[0] = pad( valueParts[0], padLength );
 123              }
 124  
 125              // Truncate whole
 126              if ( patternDigits.indexOf( '#' ) === -1 ) {
 127                  valueParts[0] = valueParts[0].slice( valueParts[0].length - padLength );
 128              }
 129          }
 130  
 131          // Add group separators
 132          index = patternParts[0].lastIndexOf( ',' );
 133  
 134          if ( index !== -1 ) {
 135              groupSize = patternParts[0].length - index - 1;
 136              remainder = patternParts[0].slice( 0, index );
 137              index = remainder.lastIndexOf( ',' );
 138              if ( index !== -1 ) {
 139                  groupSize2 = remainder.length - index - 1;
 140              }
 141          }
 142  
 143          for ( whole = valueParts[0]; whole; ) {
 144              off = groupSize ? whole.length - groupSize : 0;
 145              pieces.push( ( off > 0 ) ? whole.slice( off ) : whole );
 146              whole = ( off > 0 ) ? whole.slice( 0, off ) : '';
 147  
 148              if ( groupSize2 ) {
 149                  groupSize = groupSize2;
 150                  groupSize2 = null;
 151              }
 152          }
 153          valueParts[0] = pieces.reverse().join( options.group );
 154  
 155          return valueParts.join( options.decimal );
 156      }
 157  
 158      $.extend( mw.language, {
 159  
 160          /**
 161           * Converts a number using #getDigitTransformTable.
 162           *
 163           * @param {number} num Value to be converted
 164           * @param {boolean} [integer=false] Whether to convert the return value to an integer
 165           * @return {number|string} Formatted number
 166           */
 167          convertNumber: function ( num, integer ) {
 168              var i, tmp, transformTable, numberString, convertedNumber, pattern;
 169  
 170              pattern = mw.language.getData( mw.config.get( 'wgUserLanguage' ),
 171                  'digitGroupingPattern' ) || '#,##0.###';
 172  
 173              // Set the target transform table:
 174              transformTable = mw.language.getDigitTransformTable();
 175  
 176              if ( !transformTable ) {
 177                  return num;
 178              }
 179  
 180              // Check if the 'restore' to Latin number flag is set:
 181              if ( integer ) {
 182                  if ( parseInt( num, 10 ) === num ) {
 183                      return num;
 184                  }
 185                  tmp = [];
 186                  for ( i in transformTable ) {
 187                      tmp[ transformTable[ i ] ] = i;
 188                  }
 189                  transformTable = tmp;
 190                  numberString = num + '';
 191              } else {
 192                  numberString = mw.language.commafy( num, pattern );
 193              }
 194  
 195              convertedNumber = '';
 196              for ( i = 0; i < numberString.length; i++ ) {
 197                  if ( transformTable[ numberString[i] ] ) {
 198                      convertedNumber += transformTable[numberString[i]];
 199                  } else {
 200                      convertedNumber += numberString[i];
 201                  }
 202              }
 203              return integer ? parseInt( convertedNumber, 10 ) : convertedNumber;
 204          },
 205  
 206          /**
 207           * Get the  digit transform table for current UI language.
 208           * @return {Object|Array}
 209           */
 210          getDigitTransformTable: function () {
 211              return mw.language.getData( mw.config.get( 'wgUserLanguage' ),
 212                  'digitTransformTable' ) || [];
 213          },
 214  
 215          /**
 216           * Get the  separator transform table for current UI language.
 217           * @return {Object|Array}
 218           */
 219          getSeparatorTransformTable: function () {
 220              return mw.language.getData( mw.config.get( 'wgUserLanguage' ),
 221                  'separatorTransformTable' ) || [];
 222          },
 223  
 224          /**
 225           * Apply pattern to format value as a string.
 226           *
 227           * Using patterns from [Unicode TR35](http://www.unicode.org/reports/tr35/#Number_Format_Patterns).
 228           *
 229           * @param {number} value
 230           * @param {string} pattern Pattern string as described by Unicode TR35
 231           * @throws {Error} If unable to find a number expression in `pattern`.
 232           * @return {string}
 233           */
 234          commafy: function ( value, pattern ) {
 235              var numberPattern,
 236                  transformTable = mw.language.getSeparatorTransformTable(),
 237                  group = transformTable[','] || ',',
 238                  numberPatternRE = /[#0,]*[#0](?:\.0*#*)?/, // not precise, but good enough
 239                  decimal = transformTable['.'] || '.',
 240                  patternList = pattern.split( ';' ),
 241                  positivePattern = patternList[0];
 242  
 243              pattern = patternList[ ( value < 0 ) ? 1 : 0] || ( '-' + positivePattern );
 244              numberPattern = positivePattern.match( numberPatternRE );
 245  
 246              if ( !numberPattern ) {
 247                  throw new Error( 'unable to find a number expression in pattern: ' + pattern );
 248              }
 249  
 250              return pattern.replace( numberPatternRE, commafyNumber( value, numberPattern[0], {
 251                  decimal: decimal,
 252                  group: group
 253              } ) );
 254          }
 255  
 256      } );
 257  
 258  }( mediaWiki, jQuery ) );


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1