META-INF.resources.bower_components.globalize.src.number.parse.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jwebmp-globalize Show documentation
Show all versions of jwebmp-globalize Show documentation
The JWebSwing implementation for a full Globalization
The newest version!
define([
"../util/regexp/cf-g",
"../util/regexp/dash-g",
"../util/regexp/zs-g"
], function (regexpCfG, regexpDashG, regexpZsG) {
/**
* parse( value, properties )
*
* @value [String].
*
* @properties [Object] Parser properties is a reduced pre-processed cldr
* data set returned by numberParserProperties().
*
* Return the parsed Number (including Infinity) or NaN when value is invalid.
* ref: http://www.unicode.org/reports/tr35/tr35-numbers.html
*/
return function (value, properties) {
var grammar, invertedNuDigitsMap, invertedSymbolMap, negative, number, prefix, prefixNSuffix,
suffix, tokenizer, valid;
// Grammar:
// - Value <= NaN | PositiveNumber | NegativeNumber
// - PositiveNumber <= PositivePrefix NumberOrInf PositiveSufix
// - NegativeNumber <= NegativePrefix NumberOrInf
// - NumberOrInf <= Number | Inf
grammar = [
["nan"],
["prefix", "infinity", "suffix"],
["prefix", "number", "suffix"],
["negativePrefix", "infinity", "negativeSuffix"],
["negativePrefix", "number", "negativeSuffix"]
];
invertedSymbolMap = properties[0];
invertedNuDigitsMap = properties[1] || {};
tokenizer = properties[2];
// Loose Matching:
// - Ignore all format characters, which includes RLM, LRM or ALM used to control BIDI
// formatting.
// - Map all characters in [:Zs:] to U+0020 SPACE;
// - Map all characters in [:Dash:] to U+002D HYPHEN-MINUS;
value = value
.replace(regexpCfG, "")
.replace(regexpDashG, "-")
.replace(regexpZsG, " ");
function parse(type) {
return function (lexeme) {
// Reverse localized symbols and numbering system.
lexeme = lexeme.split("").map(function (character) {
return invertedSymbolMap[character] ||
invertedNuDigitsMap[character] ||
character;
}).join("");
switch (type) {
case "infinity":
number = Infinity;
break;
case "nan":
number = NaN;
break;
case "number":
// Remove grouping separators.
lexeme = lexeme.replace(/,/g, "");
number = +lexeme;
break;
case "prefix":
case "negativePrefix":
prefix = lexeme;
break;
case "suffix":
suffix = lexeme;
break;
case "negativeSuffix":
suffix = lexeme;
negative = true;
break;
// This should never be reached.
default:
throw new Error("Internal error");
}
return "";
};
}
function tokenizeNParse(_value, grammar) {
return grammar.some(function (statement) {
var value = _value;
// The whole grammar statement should be used (i.e., .every() return true) and value be
// entirely consumed (i.e., !value.length).
return statement.every(function (type) {
if (value.match(tokenizer[type]) === null) {
return false;
}
// Consume and parse it.
value = value.replace(tokenizer[type], parse(type));
return true;
}) && !value.length;
});
}
valid = tokenizeNParse(value, grammar);
// NaN
if (!valid || isNaN(number)) {
return NaN;
}
prefixNSuffix = "" + prefix + suffix;
// Percent
if (prefixNSuffix.indexOf("%") !== -1) {
number /= 100;
// Per mille
} else if (prefixNSuffix.indexOf("\u2030") !== -1) {
number /= 1000;
}
// Negative number
if (negative) {
number *= -1;
}
return number;
};
});