return valueParts.join( options.decimal );
}
+ /**
+ * Helper function to flip transformation tables.
+ *
+ * @param {...Object} Transformation tables
+ * @return {Object}
+ */
+ function flipTransform() {
+ var i, key, table, flipped = {};
+
+ // Ensure we strip thousand separators. This might be overwritten.
+ flipped[ ',' ] = '';
+
+ for ( i = 0; i < arguments.length; i++ ) {
+ table = arguments[ i ];
+ for ( key in table ) {
+ if ( table.hasOwnProperty( key ) ) {
+ // The thousand separator should be deleted
+ flipped[ table[ key ] ] = key === ',' ? '' : key;
+ }
+ }
+ }
+
+ return flipped;
+ }
+
$.extend( mw.language, {
/**
* @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.###';
+ var transformTable, digitTransformTable, separatorTransformTable,
+ i, numberString, convertedNumber, pattern;
- // Set the target transform table:
- transformTable = mw.language.getDigitTransformTable();
-
- if ( !transformTable ) {
+ // Quick shortcut for plain numbers
+ if ( integer && parseInt( num, 10 ) === num ) {
return num;
}
- // Check if the 'restore' to Latin number flag is set:
+ // Load the transformation tables (can be empty)
+ digitTransformTable = mw.language.getDigitTransformTable();
+ separatorTransformTable = mw.language.getSeparatorTransformTable();
+
if ( integer ) {
- if ( parseInt( num, 10 ) === num ) {
- return num;
- }
- tmp = [];
- for ( i in transformTable ) {
- tmp[ transformTable[ i ] ] = i;
- }
- transformTable = tmp;
+ // Reverse the digit transformation tables if we are doing unformatting
+ transformTable = flipTransform( separatorTransformTable, digitTransformTable );
numberString = String( num );
} else {
- // Ignore transform table if wgTranslateNumerals is false
- if ( !mw.config.get( 'wgTranslateNumerals' ) ) {
- transformTable = [];
+ // This check being here means that digits can still be unformatted
+ // even if we do not produce them. This seems sane behavior.
+ if ( mw.config.get( 'wgTranslateNumerals' ) ) {
+ transformTable = digitTransformTable;
}
+
+ // Commaying is more complex, so we handle it here separately.
+ // When unformatting, we just use separatorTransformTable.
+ pattern = mw.language.getData( mw.config.get( 'wgUserLanguage' ),
+ 'digitGroupingPattern' ) || '#,##0.###';
numberString = mw.language.commafy( num, pattern );
}
convertedNumber = '';
for ( i = 0; i < numberString.length; i++ ) {
- if ( transformTable[ numberString[ i ] ] ) {
+ if ( transformTable.hasOwnProperty( numberString[ i ] ) ) {
convertedNumber += transformTable[ numberString[ i ] ];
} else {
convertedNumber += numberString[ i ];
}
}
- return integer ? parseInt( convertedNumber, 10 ) : convertedNumber;
+
+ if ( integer ) {
+ // Parse string to integer. This loses decimals!
+ convertedNumber = parseInt( convertedNumber, 10 );
+ }
+
+ return convertedNumber;
},
/**
assert.equal( mw.language.commafy( 123456789.567, '###,###,#0.00' ), '1,234,567,89.56', 'Decimal part as group of 3 and last one 2' );
} );
+ QUnit.test( 'mw.language.convertNumber', 2, function ( assert ) {
+ mw.language.setData( 'en', 'digitGroupingPattern', null );
+ mw.language.setData( 'en', 'digitTransformTable', null );
+ mw.language.setData( 'en', 'separatorTransformTable', { ',': '.', '.': ',' } );
+ mw.config.set( 'wgUserLanguage', 'en' );
+
+ assert.equal( mw.language.convertNumber( 1800 ), '1.800', 'formatting' );
+ assert.equal( mw.language.convertNumber( "1.800", true ), '1800', 'unformatting' );
+ } );
+
function grammarTest( langCode, test ) {
// The test works only if the content language is opt.language
// because it requires [lang].js to be loaded.