mirror of
https://github.com/YunoHost-Apps/mediawiki_ynh.git
synced 2024-09-03 19:46:05 +02:00
243 lines
6.4 KiB
JavaScript
243 lines
6.4 KiB
JavaScript
/*
|
|
* Number related utilities for mediawiki.language
|
|
*/
|
|
( function ( mw, $ ) {
|
|
|
|
/**
|
|
* Pad a string to guarantee that it is at least `size` length by
|
|
* filling with the character `ch` at either the start or end of the
|
|
* string. Pads at the start, by default.
|
|
* example:
|
|
* Fill the string to length 10 with '+' characters on the right. Yields 'blah++++++'.
|
|
* pad('blah', 10, '+', true);
|
|
*
|
|
* @param {string} text The string to pad
|
|
* @param {Number} size To provide padding
|
|
* @param {string} ch Character to pad, defaults to '0'
|
|
* @param {Boolean} end Adds padding at the end if true, otherwise pads at start
|
|
* @return {string}
|
|
*/
|
|
function pad ( text, size, ch, end ) {
|
|
if ( !ch ) {
|
|
ch = '0';
|
|
}
|
|
|
|
var out = String( text ),
|
|
padStr = replicate( ch, Math.ceil( ( size - out.length ) / ch.length ) );
|
|
|
|
return end ? out + padStr : padStr + out;
|
|
}
|
|
|
|
/**
|
|
* Efficiently replicate a string n times.
|
|
*
|
|
* @param {string} str The string to replicate
|
|
* @param {Number} num Number of times to replicate the string
|
|
* @return {string}
|
|
*/
|
|
function replicate ( str, num ) {
|
|
if ( num <= 0 || !str ) {
|
|
return '';
|
|
}
|
|
|
|
var buf = [];
|
|
while (num) {
|
|
buf.push( str );
|
|
str += str;
|
|
}
|
|
return buf.join( '' );
|
|
}
|
|
|
|
/**
|
|
* Apply numeric pattern to absolute value using options. Gives no
|
|
* consideration to local customs.
|
|
*
|
|
* Adapted from dojo/number library with thanks
|
|
* http://dojotoolkit.org/reference-guide/1.8/dojo/number.html
|
|
*
|
|
* @param {Number} value the number to be formatted, ignores sign
|
|
* @param {string} pattern the number portion of a pattern (e.g. `#,##0.00`)
|
|
* @param {string} options.decimalThe decimal separator
|
|
* @param {string} options.group The group separator
|
|
*
|
|
* @return {string}
|
|
*/
|
|
function commafyNumber( value, pattern, options ) {
|
|
options = options || {
|
|
group: ',',
|
|
decimal: '.'
|
|
};
|
|
|
|
if ( isNaN( value) ) {
|
|
return value;
|
|
}
|
|
|
|
var padLength,
|
|
patternDigits,
|
|
index,
|
|
whole,
|
|
off,
|
|
remainder,
|
|
patternParts = pattern.split( '.' ),
|
|
maxPlaces = ( patternParts[1] || [] ).length,
|
|
valueParts = String( Math.abs( value ) ).split( '.' ),
|
|
fractional = valueParts[1] || '',
|
|
groupSize = 0,
|
|
groupSize2 = 0,
|
|
pieces = [];
|
|
|
|
if ( patternParts[1] ) {
|
|
// Pad fractional with trailing zeros
|
|
padLength = ( patternParts[1] && patternParts[1].lastIndexOf( '0' ) + 1 );
|
|
|
|
if ( padLength > fractional.length ) {
|
|
valueParts[1] = pad( fractional, padLength, '0', true );
|
|
}
|
|
|
|
// Truncate fractional
|
|
if ( maxPlaces < fractional.length ) {
|
|
valueParts[1] = fractional.substr( 0, maxPlaces );
|
|
}
|
|
} else {
|
|
if ( valueParts[1] ) {
|
|
valueParts.pop();
|
|
}
|
|
}
|
|
|
|
// Pad whole with leading zeros
|
|
patternDigits = patternParts[0].replace( ',', '' );
|
|
|
|
padLength = patternDigits.indexOf( '0' );
|
|
|
|
if ( padLength !== -1 ) {
|
|
padLength = patternDigits.length - padLength;
|
|
|
|
if ( padLength > valueParts[0].length ) {
|
|
valueParts[0] = pad( valueParts[0], padLength );
|
|
}
|
|
|
|
// Truncate whole
|
|
if ( patternDigits.indexOf( '#' ) === -1 ) {
|
|
valueParts[0] = valueParts[0].substr( valueParts[0].length - padLength );
|
|
}
|
|
}
|
|
|
|
// Add group separators
|
|
index = patternParts[0].lastIndexOf( ',' );
|
|
|
|
if ( index !== -1 ) {
|
|
groupSize = patternParts[0].length - index - 1;
|
|
remainder = patternParts[0].substr( 0, index );
|
|
index = remainder.lastIndexOf( ',' );
|
|
if ( index !== -1 ) {
|
|
groupSize2 = remainder.length - index - 1;
|
|
}
|
|
}
|
|
|
|
for ( whole = valueParts[0]; whole; ) {
|
|
off = whole.length - groupSize;
|
|
|
|
pieces.push( ( off > 0 ) ? whole.substr( off ) : whole );
|
|
whole = ( off > 0 ) ? whole.slice( 0, off ) : '';
|
|
|
|
if ( groupSize2 ) {
|
|
groupSize = groupSize2;
|
|
}
|
|
}
|
|
valueParts[0] = pieces.reverse().join( options.group );
|
|
|
|
return valueParts.join( options.decimal );
|
|
}
|
|
|
|
$.extend( mw.language, {
|
|
|
|
/**
|
|
* Converts a number using digitTransformTable.
|
|
*
|
|
* @param {Number} num Value to be converted
|
|
* @param {boolean} integer Convert the return value to an integer
|
|
* @return {Number|string} Formatted number
|
|
*/
|
|
convertNumber: function ( num, integer ) {
|
|
var i, tmp, transformTable, numberString, convertedNumber, pattern;
|
|
|
|
pattern = mw.language.getData( mw.config.get( 'wgUserLanguage' ),
|
|
'digitGroupingPattern' ) || '#,##0.###';
|
|
|
|
// Set the target transform table:
|
|
transformTable = mw.language.getDigitTransformTable();
|
|
|
|
if ( !transformTable ) {
|
|
return num;
|
|
}
|
|
|
|
// Check if the 'restore' to Latin number flag is set:
|
|
if ( integer ) {
|
|
if ( parseInt( num, 10 ) === num ) {
|
|
return num;
|
|
}
|
|
tmp = [];
|
|
for ( i in transformTable ) {
|
|
tmp[ transformTable[ i ] ] = i;
|
|
}
|
|
transformTable = tmp;
|
|
numberString = num + '';
|
|
} else {
|
|
numberString = mw.language.commafy( num, pattern );
|
|
}
|
|
|
|
convertedNumber = '';
|
|
for ( i = 0; i < numberString.length; i++ ) {
|
|
if ( transformTable[ numberString[i] ] ) {
|
|
convertedNumber += transformTable[numberString[i]];
|
|
} else {
|
|
convertedNumber += numberString[i];
|
|
}
|
|
}
|
|
return integer ? parseInt( convertedNumber, 10 ) : convertedNumber;
|
|
},
|
|
|
|
getDigitTransformTable: function () {
|
|
return mw.language.getData( mw.config.get( 'wgUserLanguage' ),
|
|
'digitTransformTable' ) || [];
|
|
},
|
|
|
|
getSeparatorTransformTable: function () {
|
|
return mw.language.getData( mw.config.get( 'wgUserLanguage' ),
|
|
'separatorTransformTable' ) || [];
|
|
},
|
|
|
|
/**
|
|
* Apply pattern to format value as a string using as per
|
|
* unicode.org TR35 - http://www.unicode.org/reports/tr35/#Number_Format_Patterns.
|
|
*
|
|
* @param {Number} value
|
|
* @param {string} pattern Pattern string as described by Unicode TR35
|
|
* @throws Error
|
|
* @returns {String}
|
|
*/
|
|
commafy: function ( value, pattern ) {
|
|
var numberPattern,
|
|
transformTable = mw.language.getSeparatorTransformTable(),
|
|
group = transformTable[','] || ',',
|
|
numberPatternRE = /[#0,]*[#0](?:\.0*#*)?/, // not precise, but good enough
|
|
decimal = transformTable['.'] || '.',
|
|
patternList = pattern.split( ';' ),
|
|
positivePattern = patternList[0];
|
|
|
|
pattern = patternList[ ( value < 0 ) ? 1 : 0] || ( '-' + positivePattern );
|
|
numberPattern = positivePattern.match( numberPatternRE );
|
|
|
|
if ( !numberPattern ) {
|
|
throw new Error( 'unable to find a number expression in pattern: ' + pattern );
|
|
}
|
|
|
|
return pattern.replace( numberPatternRE, commafyNumber( value, numberPattern[0], {
|
|
decimal: decimal,
|
|
group: group
|
|
} ) );
|
|
}
|
|
|
|
} );
|
|
|
|
}( mediaWiki, jQuery ) );
|