Skip to content

Commit

Permalink
Number & Currency: Add format to parts support
Browse files Browse the repository at this point in the history
- Currency: Fix code style
- Currency: pluralGenerator better error handling

Fixes #679
Fixes #680
  • Loading branch information
rxaviers committed Mar 20, 2020
1 parent d723680 commit 058d167
Show file tree
Hide file tree
Showing 35 changed files with 3,395 additions and 497 deletions.
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,21 @@ Return a function that formats a number according to the given options or locale

[Read more...](doc/api/number/number-formatter.md)

#### `.numberToPartsFormatter( [options] )`

Return a function that formats a number into parts tokens according to the given options or locale's defaults.

```javascript
.numberToPartsFormatter()( new Date() )
// > [
// { "type": "integer", "value": "3" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "142" }
// ]
```

[Read more...](doc/api/number/number-to-parts-formatter.md)

#### `.numberParser( [options] )`

Return a function that parses a string representing a number according to the given options or locale's defaults.
Expand All @@ -496,6 +511,10 @@ Return a function that parses a string representing a number according to the gi

Alias for `.numberFormatter( [options] )( value )`.

#### `.formatNumberToParts( value [, options] )`

Alias for `.numberToPartsFormatter( [options] )( value )`.

#### `.parseNumber( value [, options] )`

Alias for `.numberParser( [options] )( value )`.
Expand Down Expand Up @@ -525,10 +544,33 @@ Return a function that formats a currency according to the given options or loca

[Read more...](doc/api/currency/currency-formatter.md)

#### `.currencyToPartsFormatter( currency [, options] )`

Return a function that formats a currency into parts tokens according to the given options or locale's defaults.

```javascript
.currencyToPartsFormatter()( new Date() )
// > [
// { "type": "currency", "value": "USD" },
// { "type": "literal", "value": " " },
// { "type": "integer", "value": "69" },
// { "type": "group", "value": "," },
// { "type": "integer", "value": "900" },
// { "type": "decimal", "value": "." },
// { "type": "fraction", "value": "00" }
// ]
```

[Read more...](doc/api/currency/currency-to-parts-formatter.md)

#### `.formatCurrency( value, currency [, options] )`

Alias for `.currencyFormatter( currency [, options] )( value )`.

#### `.formatCurrencyToParts( value, currency [, options] )`

Alias for `.currencyToPartsFormatter( currency [, options] )( value )`.

### Plural module

#### `.pluralGenerator( [options] )`
Expand Down
4 changes: 3 additions & 1 deletion src/build/intro-currency-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@

"use strict";

var formatMessage = Globalize._formatMessage,
var formatMessageToParts = Globalize._formatMessageToParts,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
runtimeKey = Globalize._runtimeKey,
validateParameterPresence = Globalize._validateParameterPresence,
validateParameterTypeNumber = Globalize._validateParameterTypeNumber;
5 changes: 4 additions & 1 deletion src/build/intro-currency.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@
}(this, function( Cldr, Globalize ) {

var alwaysArray = Globalize._alwaysArray,
formatMessage = Globalize._formatMessage,
createError = Globalize._createError,
formatMessageToParts = Globalize._formatMessageToParts,
numberNumberingSystem = Globalize._numberNumberingSystem,
numberPattern = Globalize._numberPattern,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
runtimeBind = Globalize._runtimeBind,
stringPad = Globalize._stringPad,
validateCldr = Globalize._validateCldr,
Expand Down
2 changes: 2 additions & 0 deletions src/build/intro-date-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@

var createErrorUnsupportedFeature = Globalize._createErrorUnsupportedFeature,
looseMatching = Globalize._looseMatching,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
regexpEscape = Globalize._regexpEscape,
removeLiteralQuotes = Globalize._removeLiteralQuotes,
runtimeKey = Globalize._runtimeKey,
Expand Down
2 changes: 2 additions & 0 deletions src/build/intro-date.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ var createError = Globalize._createError,
looseMatching = Globalize._looseMatching,
numberNumberingSystemDigitsMap = Globalize._numberNumberingSystemDigitsMap,
numberSymbol = Globalize._numberSymbol,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
regexpEscape = Globalize._regexpEscape,
removeLiteralQuotes = Globalize._removeLiteralQuotes,
runtimeBind = Globalize._runtimeBind,
Expand Down
2 changes: 2 additions & 0 deletions src/build/intro-number-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
"use strict";

var createError = Globalize._createError,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
regexpEscape = Globalize._regexpEscape,
runtimeKey = Globalize._runtimeKey,
stringPad = Globalize._stringPad,
Expand Down
2 changes: 2 additions & 0 deletions src/build/intro-number.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
}(this, function( Cldr, Globalize ) {

var createError = Globalize._createError,
partsJoin = Globalize._partsJoin,
partsPush = Globalize._partsPush,
regexpEscape = Globalize._regexpEscape,
runtimeBind = Globalize._runtimeBind,
stringPad = Globalize._stringPad,
Expand Down
44 changes: 44 additions & 0 deletions src/common/format-message-to-parts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
define([
"./parts/push"
], function( partsPush ) {

/**
* formatMessage( message, data )
*
* @message [String] A message with optional {vars} to be replaced.
*
* @data [Array or JSON] Object with replacing-variables content.
*
* Return the formatted message. For example:
*
* - formatMessage( "{0} second", [ 1 ] );
* > [{type: "variable", value: "1", name: "0"}, {type: "literal", value: " second"}]
*
* - formatMessage( "{0}/{1}", ["m", "s"] );
* > [
* { type: "variable", value: "m", name: "0" },
* { type: "literal", value: " /" },
* { type: "variable", value: "s", name: "1" }
* ]
*/
return function( message, data ) {

var lastOffset = 0,
parts = [];

// Create parts.
message.replace( /{[0-9a-zA-Z-_. ]+}/g, function( nameIncludingBrackets, offset ) {
var name = nameIncludingBrackets.slice( 1, -1 );
partsPush( parts, "literal", message.slice( lastOffset, offset ));
partsPush( parts, "variable", data[ name ] );
parts[ parts.length - 1 ].name = name;
lastOffset += offset + nameIncludingBrackets.length;
});

// Skip empty ones such as `{ type: 'literal', value: '' }`.
return parts.filter(function( part ) {
return part.value !== "";
});
};

});
12 changes: 12 additions & 0 deletions src/common/parts/join.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
define(function() {

/**
* Returns joined parts values.
*/
return function( parts ) {
return parts.map( function( part ) {
return part.value;
}).join( "" );
};

});
17 changes: 17 additions & 0 deletions src/common/parts/push.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
define(function() {

/**
* Pushes part to parts array, concat two consecutive parts of the same type.
*/
return function( parts, type, value ) {

// Concat two consecutive parts of same type
if ( parts.length && parts[ parts.length - 1 ].type === type ) {
parts[ parts.length - 1 ].value += value;
return;
}

parts.push( { type: type, value: value } );
};

});
11 changes: 9 additions & 2 deletions src/core-runtime.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
define([
"./common/create-error",
"./common/format-message",
"./common/format-message-to-parts",
"./common/parts/join",
"./common/parts/push",
"./common/runtime-key",
"./common/validate/parameter-presence",
"./common/validate/parameter-type",
"./common/validate/parameter-type/string",
"./util/regexp/escape",
"./util/string/pad"
], function( createError, formatMessage, runtimeKey, validateParameterPresence,
validateParameterType, validateParameterTypeString, regexpEscape, stringPad ) {
], function( createError, formatMessage, formatMessageToParts, partsJoin, partsPush, runtimeKey,
validateParameterPresence, validateParameterType, validateParameterTypeString, regexpEscape,
stringPad ) {

function Globalize( locale ) {
if ( !( this instanceof Globalize ) ) {
Expand All @@ -32,6 +36,9 @@ Globalize.locale = function( locale ) {

Globalize._createError = createError;
Globalize._formatMessage = formatMessage;
Globalize._formatMessageToParts = formatMessageToParts;
Globalize._partsJoin = partsJoin;
Globalize._partsPush = partsPush;
Globalize._regexpEscape = regexpEscape;
Globalize._runtimeKey = runtimeKey;
Globalize._stringPad = stringPad;
Expand Down
15 changes: 11 additions & 4 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ define([
"cldr",
"./common/create-error",
"./common/format-message",
"./common/format-message-to-parts",
"./common/parts/join",
"./common/parts/push",
"./common/runtime-bind",
"./common/validate",
"./common/validate/cldr",
Expand All @@ -19,10 +22,11 @@ define([
"./util/string/pad",

"cldr/event"
], function( Cldr, createError, formatMessage, runtimeBind, validate, validateCldr,
validateDefaultLocale, validateParameterPresence, validateParameterRange, validateParameterType,
validateParameterTypeLocale, validateParameterTypePlainObject, alwaysArray, alwaysCldr,
isPlainObject, objectExtend, regexpEscape, stringPad ) {
], function( Cldr, createError, formatMessage, formatMessageToParts, partsJoin, partsPush,
runtimeBind, validate, validateCldr, validateDefaultLocale, validateParameterPresence,
validateParameterRange, validateParameterType, validateParameterTypeLocale,
validateParameterTypePlainObject, alwaysArray, alwaysCldr, isPlainObject, objectExtend,
regexpEscape, stringPad ) {

function validateLikelySubtags( cldr ) {
cldr.once( "get", validateCldr );
Expand Down Expand Up @@ -92,8 +96,11 @@ Globalize.locale = function( locale ) {
Globalize._alwaysArray = alwaysArray;
Globalize._createError = createError;
Globalize._formatMessage = formatMessage;
Globalize._formatMessageToParts = formatMessageToParts;
Globalize._isPlainObject = isPlainObject;
Globalize._objectExtend = objectExtend;
Globalize._partsJoin = partsJoin;
Globalize._partsPush = partsPush;
Globalize._regexpEscape = regexpEscape;
Globalize._runtimeBind = runtimeBind;
Globalize._stringPad = stringPad;
Expand Down
20 changes: 19 additions & 1 deletion src/currency-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,30 @@ define([
"./core-runtime",
"./currency/formatter-fn",
"./currency/name-format",
"./currency/to-parts-formatter-fn",

"./number-runtime"
], function( runtimeKey, validateParameterPresence, validateParameterTypeNumber, Globalize,
currencyFormatterFn, currencyNameFormat ) {
currencyFormatterFn, currencyNameFormat, currencyToPartsFormatterFn ) {

Globalize._currencyFormatterFn = currencyFormatterFn;
Globalize._currencyNameFormat = currencyNameFormat;
Globalize._currencyToPartsFormatterFn = currencyToPartsFormatterFn;

Globalize.currencyFormatter =
Globalize.prototype.currencyFormatter = function( currency, options ) {
options = options || {};
return Globalize[ runtimeKey( "currencyFormatter", this._locale, [ currency, options ] ) ];
};

Globalize.currencyToPartsFormatter =
Globalize.prototype.currencyToPartsFormatter = function( currency, options ) {
options = options || {};
return Globalize[
runtimeKey( "currencyToPartsFormatter", this._locale, [ currency, options ] )
];
};

Globalize.formatCurrency =
Globalize.prototype.formatCurrency = function( value, currency, options ) {
validateParameterPresence( value, "value" );
Expand All @@ -27,6 +37,14 @@ Globalize.prototype.formatCurrency = function( value, currency, options ) {
return this.currencyFormatter( currency, options )( value );
};

Globalize.formatCurrencyToParts =
Globalize.prototype.formatCurrencyToParts = function( value, currency, options ) {
validateParameterPresence( value, "value" );
validateParameterTypeNumber( value, "value" );

return this.currencyToPartsFormatter( currency, options )( value );
};

return Globalize;

});
Loading

0 comments on commit 058d167

Please sign in to comment.