summaryrefslogtreecommitdiff
path: root/lib/dojo/number.js
diff options
context:
space:
mode:
authorAndrew Dolgov <[email protected]>2011-03-04 19:02:28 +0300
committerAndrew Dolgov <[email protected]>2011-03-04 19:02:59 +0300
commita089699c8915636ba4f158d77dba9b012bc93208 (patch)
treeb2d7d051f1f55d44a6be07d3ee137e5a7ccfcefb /lib/dojo/number.js
parentcfad9259a6feacfa8194b1312770ae6db1ecce50 (diff)
build custom layer of Dojo to speed up loading of tt-rss (refs #293)
Diffstat (limited to 'lib/dojo/number.js')
-rw-r--r--lib/dojo/number.js849
1 files changed, 561 insertions, 288 deletions
diff --git a/lib/dojo/number.js b/lib/dojo/number.js
index 95a2c5022..33aa6dd52 100644
--- a/lib/dojo/number.js
+++ b/lib/dojo/number.js
@@ -5,307 +5,580 @@
*/
-if(!dojo._hasResource["dojo.number"]){
-dojo._hasResource["dojo.number"]=true;
+if(!dojo._hasResource["dojo.number"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojo.number"] = true;
dojo.provide("dojo.number");
+
dojo.require("dojo.i18n");
-dojo.requireLocalization("dojo.cldr","number",null,"ROOT,ar,ca,cs,da,de,el,en,en-au,en-gb,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh");
+dojo.requireLocalization("dojo.cldr", "number", null, "ROOT,ar,ca,cs,da,de,el,en,en-au,en-gb,es,fi,fr,he,hu,it,ja,ko,nb,nl,pl,pt,pt-pt,ru,sk,sl,sv,th,tr,zh");
dojo.require("dojo.string");
dojo.require("dojo.regexp");
-dojo.number.format=function(_1,_2){
-_2=dojo.mixin({},_2||{});
-var _3=dojo.i18n.normalizeLocale(_2.locale),_4=dojo.i18n.getLocalization("dojo.cldr","number",_3);
-_2.customs=_4;
-var _5=_2.pattern||_4[(_2.type||"decimal")+"Format"];
-if(isNaN(_1)||Math.abs(_1)==Infinity){
-return null;
-}
-return dojo.number._applyPattern(_1,_5,_2);
-};
-dojo.number._numberPatternRE=/[#0,]*[#0](?:\.0*#*)?/;
-dojo.number._applyPattern=function(_6,_7,_8){
-_8=_8||{};
-var _9=_8.customs.group,_a=_8.customs.decimal,_b=_7.split(";"),_c=_b[0];
-_7=_b[(_6<0)?1:0]||("-"+_c);
-if(_7.indexOf("%")!=-1){
-_6*=100;
-}else{
-if(_7.indexOf("‰")!=-1){
-_6*=1000;
-}else{
-if(_7.indexOf("¤")!=-1){
-_9=_8.customs.currencyGroup||_9;
-_a=_8.customs.currencyDecimal||_a;
-_7=_7.replace(/\u00a4{1,3}/,function(_d){
-var _e=["symbol","currency","displayName"][_d.length-1];
-return _8[_e]||_8.currency||"";
-});
-}else{
-if(_7.indexOf("E")!=-1){
-throw new Error("exponential notation not supported");
-}
-}
-}
-}
-var _f=dojo.number._numberPatternRE;
-var _10=_c.match(_f);
-if(!_10){
-throw new Error("unable to find a number expression in pattern: "+_7);
-}
-if(_8.fractional===false){
-_8.places=0;
-}
-return _7.replace(_f,dojo.number._formatAbsolute(_6,_10[0],{decimal:_a,group:_9,places:_8.places,round:_8.round}));
-};
-dojo.number.round=function(_11,_12,_13){
-var _14=10/(_13||10);
-return (_14*+_11).toFixed(_12)/_14;
-};
-if((0.9).toFixed()==0){
-(function(){
-var _15=dojo.number.round;
-dojo.number.round=function(v,p,m){
-var d=Math.pow(10,-p||0),a=Math.abs(v);
-if(!v||a>=d||a*Math.pow(10,p+1)<5){
-d=0;
-}
-return _15(v,p,m)+(v>0?d:-d);
-};
-})();
-}
-dojo.number._formatAbsolute=function(_16,_17,_18){
-_18=_18||{};
-if(_18.places===true){
-_18.places=0;
-}
-if(_18.places===Infinity){
-_18.places=6;
-}
-var _19=_17.split("."),_1a=typeof _18.places=="string"&&_18.places.indexOf(","),_1b=_18.places;
-if(_1a){
-_1b=_18.places.substring(_1a+1);
-}else{
-if(!(_1b>=0)){
-_1b=(_19[1]||[]).length;
-}
-}
-if(!(_18.round<0)){
-_16=dojo.number.round(_16,_1b,_18.round);
-}
-var _1c=String(Math.abs(_16)).split("."),_1d=_1c[1]||"";
-if(_19[1]||_18.places){
-if(_1a){
-_18.places=_18.places.substring(0,_1a);
-}
-var pad=_18.places!==undefined?_18.places:(_19[1]&&_19[1].lastIndexOf("0")+1);
-if(pad>_1d.length){
-_1c[1]=dojo.string.pad(_1d,pad,"0",true);
-}
-if(_1b<_1d.length){
-_1c[1]=_1d.substr(0,_1b);
-}
-}else{
-if(_1c[1]){
-_1c.pop();
-}
-}
-var _1e=_19[0].replace(",","");
-pad=_1e.indexOf("0");
-if(pad!=-1){
-pad=_1e.length-pad;
-if(pad>_1c[0].length){
-_1c[0]=dojo.string.pad(_1c[0],pad);
-}
-if(_1e.indexOf("#")==-1){
-_1c[0]=_1c[0].substr(_1c[0].length-pad);
-}
-}
-var _1f=_19[0].lastIndexOf(","),_20,_21;
-if(_1f!=-1){
-_20=_19[0].length-_1f-1;
-var _22=_19[0].substr(0,_1f);
-_1f=_22.lastIndexOf(",");
-if(_1f!=-1){
-_21=_22.length-_1f-1;
-}
-}
-var _23=[];
-for(var _24=_1c[0];_24;){
-var off=_24.length-_20;
-_23.push((off>0)?_24.substr(off):_24);
-_24=(off>0)?_24.slice(0,off):"";
-if(_21){
-_20=_21;
-delete _21;
-}
+
+
+/*=====
+dojo.number = {
+ // summary: localized formatting and parsing routines for Number
}
-_1c[0]=_23.reverse().join(_18.group||",");
-return _1c.join(_18.decimal||".");
-};
-dojo.number.regexp=function(_25){
-return dojo.number._parseInfo(_25).regexp;
+
+dojo.number.__FormatOptions = function(){
+ // pattern: String?
+ // override [formatting pattern](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+ // with this string. Default value is based on locale. Overriding this property will defeat
+ // localization. Literal characters in patterns are not supported.
+ // type: String?
+ // choose a format type based on the locale from the following:
+ // decimal, scientific (not yet supported), percent, currency. decimal by default.
+ // places: Number?
+ // fixed number of decimal places to show. This overrides any
+ // information in the provided pattern.
+ // round: Number?
+ // 5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
+ // means do not round.
+ // locale: String?
+ // override the locale used to determine formatting rules
+ // fractional: Boolean?
+ // If false, show no decimal places, overriding places and pattern settings.
+ this.pattern = pattern;
+ this.type = type;
+ this.places = places;
+ this.round = round;
+ this.locale = locale;
+ this.fractional = fractional;
+}
+=====*/
+
+dojo.number.format = function(/*Number*/value, /*dojo.number.__FormatOptions?*/options){
+ // summary:
+ // Format a Number as a String, using locale-specific settings
+ // description:
+ // Create a string from a Number using a known localized pattern.
+ // Formatting patterns appropriate to the locale are chosen from the
+ // [Common Locale Data Repository](http://unicode.org/cldr) as well as the appropriate symbols and
+ // delimiters.
+ // If value is Infinity, -Infinity, or is not a valid JavaScript number, return null.
+ // value:
+ // the number to be formatted
+
+ options = dojo.mixin({}, options || {});
+ var locale = dojo.i18n.normalizeLocale(options.locale),
+ bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale);
+ options.customs = bundle;
+ var pattern = options.pattern || bundle[(options.type || "decimal") + "Format"];
+ if(isNaN(value) || Math.abs(value) == Infinity){ return null; } // null
+ return dojo.number._applyPattern(value, pattern, options); // String
};
-dojo.number._parseInfo=function(_26){
-_26=_26||{};
-var _27=dojo.i18n.normalizeLocale(_26.locale),_28=dojo.i18n.getLocalization("dojo.cldr","number",_27),_29=_26.pattern||_28[(_26.type||"decimal")+"Format"],_2a=_28.group,_2b=_28.decimal,_2c=1;
-if(_29.indexOf("%")!=-1){
-_2c/=100;
-}else{
-if(_29.indexOf("‰")!=-1){
-_2c/=1000;
-}else{
-var _2d=_29.indexOf("¤")!=-1;
-if(_2d){
-_2a=_28.currencyGroup||_2a;
-_2b=_28.currencyDecimal||_2b;
-}
-}
-}
-var _2e=_29.split(";");
-if(_2e.length==1){
-_2e.push("-"+_2e[0]);
-}
-var re=dojo.regexp.buildGroupRE(_2e,function(_2f){
-_2f="(?:"+dojo.regexp.escapeString(_2f,".")+")";
-return _2f.replace(dojo.number._numberPatternRE,function(_30){
-var _31={signed:false,separator:_26.strict?_2a:[_2a,""],fractional:_26.fractional,decimal:_2b,exponent:false},_32=_30.split("."),_33=_26.places;
-if(_32.length==1&&_2c!=1){
-_32[1]="###";
-}
-if(_32.length==1||_33===0){
-_31.fractional=false;
-}else{
-if(_33===undefined){
-_33=_26.pattern?_32[1].lastIndexOf("0")+1:Infinity;
-}
-if(_33&&_26.fractional==undefined){
-_31.fractional=true;
-}
-if(!_26.places&&(_33<_32[1].length)){
-_33+=","+_32[1].length;
-}
-_31.places=_33;
-}
-var _34=_32[0].split(",");
-if(_34.length>1){
-_31.groupSize=_34.pop().length;
-if(_34.length>1){
-_31.groupSize2=_34.pop().length;
-}
-}
-return "("+dojo.number._realNumberRegexp(_31)+")";
-});
-},true);
-if(_2d){
-re=re.replace(/([\s\xa0]*)(\u00a4{1,3})([\s\xa0]*)/g,function(_35,_36,_37,_38){
-var _39=["symbol","currency","displayName"][_37.length-1],_3a=dojo.regexp.escapeString(_26[_39]||_26.currency||"");
-_36=_36?"[\\s\\xa0]":"";
-_38=_38?"[\\s\\xa0]":"";
-if(!_26.strict){
-if(_36){
-_36+="*";
-}
-if(_38){
-_38+="*";
+
+//dojo.number._numberPatternRE = /(?:[#0]*,?)*[#0](?:\.0*#*)?/; // not precise, but good enough
+dojo.number._numberPatternRE = /[#0,]*[#0](?:\.0*#*)?/; // not precise, but good enough
+
+dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.number.__FormatOptions?*/options){
+ // summary:
+ // Apply pattern to format value as a string using options. Gives no
+ // consideration to local customs.
+ // value:
+ // the number to be formatted.
+ // pattern:
+ // a pattern string as described by
+ // [unicode.org TR35](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+ // options: dojo.number.__FormatOptions?
+ // _applyPattern is usually called via `dojo.number.format()` which
+ // populates an extra property in the options parameter, "customs".
+ // The customs object specifies group and decimal parameters if set.
+
+ //TODO: support escapes
+ options = options || {};
+ var group = options.customs.group,
+ decimal = options.customs.decimal,
+ patternList = pattern.split(';'),
+ positivePattern = patternList[0];
+ pattern = patternList[(value < 0) ? 1 : 0] || ("-" + positivePattern);
+
+ //TODO: only test against unescaped
+ if(pattern.indexOf('%') != -1){
+ value *= 100;
+ }else if(pattern.indexOf('\u2030') != -1){
+ value *= 1000; // per mille
+ }else if(pattern.indexOf('\u00a4') != -1){
+ group = options.customs.currencyGroup || group;//mixins instead?
+ decimal = options.customs.currencyDecimal || decimal;// Should these be mixins instead?
+ pattern = pattern.replace(/\u00a4{1,3}/, function(match){
+ var prop = ["symbol", "currency", "displayName"][match.length-1];
+ return options[prop] || options.currency || "";
+ });
+ }else if(pattern.indexOf('E') != -1){
+ throw new Error("exponential notation not supported");
+ }
+
+ //TODO: support @ sig figs?
+ var numberPatternRE = dojo.number._numberPatternRE;
+ var numberPattern = positivePattern.match(numberPatternRE);
+ if(!numberPattern){
+ throw new Error("unable to find a number expression in pattern: "+pattern);
+ }
+ if(options.fractional === false){ options.places = 0; }
+ return pattern.replace(numberPatternRE,
+ dojo.number._formatAbsolute(value, numberPattern[0], {decimal: decimal, group: group, places: options.places, round: options.round}));
}
-return "(?:"+_36+_3a+_38+")?";
+
+dojo.number.round = function(/*Number*/value, /*Number?*/places, /*Number?*/increment){
+ // summary:
+ // Rounds to the nearest value with the given number of decimal places, away from zero
+ // description:
+ // Rounds to the nearest value with the given number of decimal places, away from zero if equal.
+ // Similar to Number.toFixed(), but compensates for browser quirks. Rounding can be done by
+ // fractional increments also, such as the nearest quarter.
+ // NOTE: Subject to floating point errors. See dojox.math.round for experimental workaround.
+ // value:
+ // The number to round
+ // places:
+ // The number of decimal places where rounding takes place. Defaults to 0 for whole rounding.
+ // Must be non-negative.
+ // increment:
+ // Rounds next place to nearest value of increment/10. 10 by default.
+ // example:
+ // >>> dojo.number.round(-0.5)
+ // -1
+ // >>> dojo.number.round(162.295, 2)
+ // 162.29 // note floating point error. Should be 162.3
+ // >>> dojo.number.round(10.71, 0, 2.5)
+ // 10.75
+ var factor = 10 / (increment || 10);
+ return (factor * +value).toFixed(places) / factor; // Number
}
-return _36+_3a+_38;
-});
+
+if((0.9).toFixed() == 0){
+ // (isIE) toFixed() bug workaround: Rounding fails on IE when most significant digit
+ // is just after the rounding place and is >=5
+ (function(){
+ var round = dojo.number.round;
+ dojo.number.round = function(v, p, m){
+ var d = Math.pow(10, -p || 0), a = Math.abs(v);
+ if(!v || a >= d || a * Math.pow(10, p + 1) < 5){
+ d = 0;
+ }
+ return round(v, p, m) + (v > 0 ? d : -d);
+ }
+ })();
}
-return {regexp:re.replace(/[\xa0 ]/g,"[\\s\\xa0]"),group:_2a,decimal:_2b,factor:_2c};
+
+/*=====
+dojo.number.__FormatAbsoluteOptions = function(){
+ // decimal: String?
+ // the decimal separator
+ // group: String?
+ // the group separator
+ // places: Number?|String?
+ // number of decimal places. the range "n,m" will format to m places.
+ // round: Number?
+ // 5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
+ // means don't round.
+ this.decimal = decimal;
+ this.group = group;
+ this.places = places;
+ this.round = round;
+}
+=====*/
+
+dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*dojo.number.__FormatAbsoluteOptions?*/options){
+ // summary:
+ // Apply numeric pattern to absolute value using options. Gives no
+ // consideration to local customs.
+ // value:
+ // the number to be formatted, ignores sign
+ // pattern:
+ // the number portion of a pattern (e.g. `#,##0.00`)
+ options = options || {};
+ if(options.places === true){options.places=0;}
+ if(options.places === Infinity){options.places=6;} // avoid a loop; pick a limit
+
+ var patternParts = pattern.split("."),
+ comma = typeof options.places == "string" && options.places.indexOf(","),
+ maxPlaces = options.places;
+ if(comma){
+ maxPlaces = options.places.substring(comma + 1);
+ }else if(!(maxPlaces >= 0)){
+ maxPlaces = (patternParts[1] || []).length;
+ }
+ if(!(options.round < 0)){
+ value = dojo.number.round(value, maxPlaces, options.round);
+ }
+
+ var valueParts = String(Math.abs(value)).split("."),
+ fractional = valueParts[1] || "";
+ if(patternParts[1] || options.places){
+ if(comma){
+ options.places = options.places.substring(0, comma);
+ }
+ // Pad fractional with trailing zeros
+ var pad = options.places !== undefined ? options.places : (patternParts[1] && patternParts[1].lastIndexOf("0") + 1);
+ if(pad > fractional.length){
+ valueParts[1] = dojo.string.pad(fractional, pad, '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
+ var patternDigits = patternParts[0].replace(',', '');
+ pad = patternDigits.indexOf("0");
+ if(pad != -1){
+ pad = patternDigits.length - pad;
+ if(pad > valueParts[0].length){
+ valueParts[0] = dojo.string.pad(valueParts[0], pad);
+ }
+
+ // Truncate whole
+ if(patternDigits.indexOf("#") == -1){
+ valueParts[0] = valueParts[0].substr(valueParts[0].length - pad);
+ }
+ }
+
+ // Add group separators
+ var index = patternParts[0].lastIndexOf(','),
+ groupSize, groupSize2;
+ if(index != -1){
+ groupSize = patternParts[0].length - index - 1;
+ var remainder = patternParts[0].substr(0, index);
+ index = remainder.lastIndexOf(',');
+ if(index != -1){
+ groupSize2 = remainder.length - index - 1;
+ }
+ }
+ var pieces = [];
+ for(var whole = valueParts[0]; whole;){
+ var off = whole.length - groupSize;
+ pieces.push((off > 0) ? whole.substr(off) : whole);
+ whole = (off > 0) ? whole.slice(0, off) : "";
+ if(groupSize2){
+ groupSize = groupSize2;
+ delete groupSize2;
+ }
+ }
+ valueParts[0] = pieces.reverse().join(options.group || ",");
+
+ return valueParts.join(options.decimal || ".");
};
-dojo.number.parse=function(_3b,_3c){
-var _3d=dojo.number._parseInfo(_3c),_3e=(new RegExp("^"+_3d.regexp+"$")).exec(_3b);
-if(!_3e){
-return NaN;
-}
-var _3f=_3e[1];
-if(!_3e[1]){
-if(!_3e[2]){
-return NaN;
+
+/*=====
+dojo.number.__RegexpOptions = function(){
+ // pattern: String?
+ // override [formatting pattern](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+ // with this string. Default value is based on locale. Overriding this property will defeat
+ // localization.
+ // type: String?
+ // choose a format type based on the locale from the following:
+ // decimal, scientific (not yet supported), percent, currency. decimal by default.
+ // locale: String?
+ // override the locale used to determine formatting rules
+ // strict: Boolean?
+ // strict parsing, false by default. Strict parsing requires input as produced by the format() method.
+ // Non-strict is more permissive, e.g. flexible on white space, omitting thousands separators
+ // places: Number|String?
+ // number of decimal places to accept: Infinity, a positive number, or
+ // a range "n,m". Defined by pattern or Infinity if pattern not provided.
+ this.pattern = pattern;
+ this.type = type;
+ this.locale = locale;
+ this.strict = strict;
+ this.places = places;
+}
+=====*/
+dojo.number.regexp = function(/*dojo.number.__RegexpOptions?*/options){
+ // summary:
+ // Builds the regular needed to parse a number
+ // description:
+ // Returns regular expression with positive and negative match, group
+ // and decimal separators
+ return dojo.number._parseInfo(options).regexp; // String
}
-_3f=_3e[2];
-_3d.factor*=-1;
+
+dojo.number._parseInfo = function(/*Object?*/options){
+ options = options || {};
+ var locale = dojo.i18n.normalizeLocale(options.locale),
+ bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale),
+ pattern = options.pattern || bundle[(options.type || "decimal") + "Format"],
+//TODO: memoize?
+ group = bundle.group,
+ decimal = bundle.decimal,
+ factor = 1;
+
+ if(pattern.indexOf('%') != -1){
+ factor /= 100;
+ }else if(pattern.indexOf('\u2030') != -1){
+ factor /= 1000; // per mille
+ }else{
+ var isCurrency = pattern.indexOf('\u00a4') != -1;
+ if(isCurrency){
+ group = bundle.currencyGroup || group;
+ decimal = bundle.currencyDecimal || decimal;
+ }
+ }
+
+ //TODO: handle quoted escapes
+ var patternList = pattern.split(';');
+ if(patternList.length == 1){
+ patternList.push("-" + patternList[0]);
+ }
+
+ var re = dojo.regexp.buildGroupRE(patternList, function(pattern){
+ pattern = "(?:"+dojo.regexp.escapeString(pattern, '.')+")";
+ return pattern.replace(dojo.number._numberPatternRE, function(format){
+ var flags = {
+ signed: false,
+ separator: options.strict ? group : [group,""],
+ fractional: options.fractional,
+ decimal: decimal,
+ exponent: false
+ },
+
+ parts = format.split('.'),
+ places = options.places;
+
+ // special condition for percent (factor != 1)
+ // allow decimal places even if not specified in pattern
+ if(parts.length == 1 && factor != 1){
+ parts[1] = "###";
+ }
+ if(parts.length == 1 || places === 0){
+ flags.fractional = false;
+ }else{
+ if(places === undefined){ places = options.pattern ? parts[1].lastIndexOf('0') + 1 : Infinity; }
+ if(places && options.fractional == undefined){flags.fractional = true;} // required fractional, unless otherwise specified
+ if(!options.places && (places < parts[1].length)){ places += "," + parts[1].length; }
+ flags.places = places;
+ }
+ var groups = parts[0].split(',');
+ if(groups.length > 1){
+ flags.groupSize = groups.pop().length;
+ if(groups.length > 1){
+ flags.groupSize2 = groups.pop().length;
+ }
+ }
+ return "("+dojo.number._realNumberRegexp(flags)+")";
+ });
+ }, true);
+
+ if(isCurrency){
+ // substitute the currency symbol for the placeholder in the pattern
+ re = re.replace(/([\s\xa0]*)(\u00a4{1,3})([\s\xa0]*)/g, function(match, before, target, after){
+ var prop = ["symbol", "currency", "displayName"][target.length-1],
+ symbol = dojo.regexp.escapeString(options[prop] || options.currency || "");
+ before = before ? "[\\s\\xa0]" : "";
+ after = after ? "[\\s\\xa0]" : "";
+ if(!options.strict){
+ if(before){before += "*";}
+ if(after){after += "*";}
+ return "(?:"+before+symbol+after+")?";
+ }
+ return before+symbol+after;
+ });
+ }
+
+//TODO: substitute localized sign/percent/permille/etc.?
+
+ // normalize whitespace and return
+ return {regexp: re.replace(/[\xa0 ]/g, "[\\s\\xa0]"), group: group, decimal: decimal, factor: factor}; // Object
}
-_3f=_3f.replace(new RegExp("["+_3d.group+"\\s\\xa0"+"]","g"),"").replace(_3d.decimal,".");
-return _3f*_3d.factor;
+
+/*=====
+dojo.number.__ParseOptions = function(){
+ // pattern: String?
+ // override [formatting pattern](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+ // with this string. Default value is based on locale. Overriding this property will defeat
+ // localization. Literal characters in patterns are not supported.
+ // type: String?
+ // choose a format type based on the locale from the following:
+ // decimal, scientific (not yet supported), percent, currency. decimal by default.
+ // locale: String?
+ // override the locale used to determine formatting rules
+ // strict: Boolean?
+ // strict parsing, false by default. Strict parsing requires input as produced by the format() method.
+ // Non-strict is more permissive, e.g. flexible on white space, omitting thousands separators
+ // fractional: Boolean?|Array?
+ // Whether to include the fractional portion, where the number of decimal places are implied by pattern
+ // or explicit 'places' parameter. The value [true,false] makes the fractional portion optional.
+ this.pattern = pattern;
+ this.type = type;
+ this.locale = locale;
+ this.strict = strict;
+ this.fractional = fractional;
+}
+=====*/
+dojo.number.parse = function(/*String*/expression, /*dojo.number.__ParseOptions?*/options){
+ // summary:
+ // Convert a properly formatted string to a primitive Number, using
+ // locale-specific settings.
+ // description:
+ // Create a Number from a string using a known localized pattern.
+ // Formatting patterns are chosen appropriate to the locale
+ // and follow the syntax described by
+ // [unicode.org TR35](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
+ // Note that literal characters in patterns are not supported.
+ // expression:
+ // A string representation of a Number
+ var info = dojo.number._parseInfo(options),
+ results = (new RegExp("^"+info.regexp+"$")).exec(expression);
+ if(!results){
+ return NaN; //NaN
+ }
+ var absoluteMatch = results[1]; // match for the positive expression
+ if(!results[1]){
+ if(!results[2]){
+ return NaN; //NaN
+ }
+ // matched the negative pattern
+ absoluteMatch =results[2];
+ info.factor *= -1;
+ }
+
+ // Transform it to something Javascript can parse as a number. Normalize
+ // decimal point and strip out group separators or alternate forms of whitespace
+ absoluteMatch = absoluteMatch.
+ replace(new RegExp("["+info.group + "\\s\\xa0"+"]", "g"), "").
+ replace(info.decimal, ".");
+ // Adjust for negative sign, percent, etc. as necessary
+ return absoluteMatch * info.factor; //Number
};
-dojo.number._realNumberRegexp=function(_40){
-_40=_40||{};
-if(!("places" in _40)){
-_40.places=Infinity;
-}
-if(typeof _40.decimal!="string"){
-_40.decimal=".";
-}
-if(!("fractional" in _40)||/^0/.test(_40.places)){
-_40.fractional=[true,false];
-}
-if(!("exponent" in _40)){
-_40.exponent=[true,false];
-}
-if(!("eSigned" in _40)){
-_40.eSigned=[true,false];
-}
-var _41=dojo.number._integerRegexp(_40),_42=dojo.regexp.buildGroupRE(_40.fractional,function(q){
-var re="";
-if(q&&(_40.places!==0)){
-re="\\"+_40.decimal;
-if(_40.places==Infinity){
-re="(?:"+re+"\\d+)?";
-}else{
-re+="\\d{"+_40.places+"}";
-}
-}
-return re;
-},true);
-var _43=dojo.regexp.buildGroupRE(_40.exponent,function(q){
-if(q){
-return "([eE]"+dojo.number._integerRegexp({signed:_40.eSigned})+")";
-}
-return "";
-});
-var _44=_41+_42;
-if(_42){
-_44="(?:(?:"+_44+")|(?:"+_42+"))";
-}
-return _44+_43;
+
+/*=====
+dojo.number.__RealNumberRegexpFlags = function(){
+ // places: Number?
+ // The integer number of decimal places or a range given as "n,m". If
+ // not given, the decimal part is optional and the number of places is
+ // unlimited.
+ // decimal: String?
+ // A string for the character used as the decimal point. Default
+ // is ".".
+ // fractional: Boolean?|Array?
+ // Whether decimal places are used. Can be true, false, or [true,
+ // false]. Default is [true, false] which means optional.
+ // exponent: Boolean?|Array?
+ // Express in exponential notation. Can be true, false, or [true,
+ // false]. Default is [true, false], (i.e. will match if the
+ // exponential part is present are not).
+ // eSigned: Boolean?|Array?
+ // The leading plus-or-minus sign on the exponent. Can be true,
+ // false, or [true, false]. Default is [true, false], (i.e. will
+ // match if it is signed or unsigned). flags in regexp.integer can be
+ // applied.
+ this.places = places;
+ this.decimal = decimal;
+ this.fractional = fractional;
+ this.exponent = exponent;
+ this.eSigned = eSigned;
+}
+=====*/
+
+dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*/flags){
+ // summary:
+ // Builds a regular expression to match a real number in exponential
+ // notation
+
+ // assign default values to missing parameters
+ flags = flags || {};
+ //TODO: use mixin instead?
+ if(!("places" in flags)){ flags.places = Infinity; }
+ if(typeof flags.decimal != "string"){ flags.decimal = "."; }
+ if(!("fractional" in flags) || /^0/.test(flags.places)){ flags.fractional = [true, false]; }
+ if(!("exponent" in flags)){ flags.exponent = [true, false]; }
+ if(!("eSigned" in flags)){ flags.eSigned = [true, false]; }
+
+ var integerRE = dojo.number._integerRegexp(flags),
+ decimalRE = dojo.regexp.buildGroupRE(flags.fractional,
+ function(q){
+ var re = "";
+ if(q && (flags.places!==0)){
+ re = "\\" + flags.decimal;
+ if(flags.places == Infinity){
+ re = "(?:" + re + "\\d+)?";
+ }else{
+ re += "\\d{" + flags.places + "}";
+ }
+ }
+ return re;
+ },
+ true
+ );
+
+ var exponentRE = dojo.regexp.buildGroupRE(flags.exponent,
+ function(q){
+ if(q){ return "([eE]" + dojo.number._integerRegexp({ signed: flags.eSigned}) + ")"; }
+ return "";
+ }
+ );
+
+ var realRE = integerRE + decimalRE;
+ // allow for decimals without integers, e.g. .25
+ if(decimalRE){realRE = "(?:(?:"+ realRE + ")|(?:" + decimalRE + "))";}
+ return realRE + exponentRE; // String
};
-dojo.number._integerRegexp=function(_45){
-_45=_45||{};
-if(!("signed" in _45)){
-_45.signed=[true,false];
-}
-if(!("separator" in _45)){
-_45.separator="";
-}else{
-if(!("groupSize" in _45)){
-_45.groupSize=3;
-}
-}
-var _46=dojo.regexp.buildGroupRE(_45.signed,function(q){
-return q?"[-+]":"";
-},true);
-var _47=dojo.regexp.buildGroupRE(_45.separator,function(sep){
-if(!sep){
-return "(?:\\d+)";
-}
-sep=dojo.regexp.escapeString(sep);
-if(sep==" "){
-sep="\\s";
-}else{
-if(sep==" "){
-sep="\\s\\xa0";
-}
-}
-var grp=_45.groupSize,_48=_45.groupSize2;
-if(_48){
-var _49="(?:0|[1-9]\\d{0,"+(_48-1)+"}(?:["+sep+"]\\d{"+_48+"})*["+sep+"]\\d{"+grp+"})";
-return ((grp-_48)>0)?"(?:"+_49+"|(?:0|[1-9]\\d{0,"+(grp-1)+"}))":_49;
+
+/*=====
+dojo.number.__IntegerRegexpFlags = function(){
+ // signed: Boolean?
+ // The leading plus-or-minus sign. Can be true, false, or `[true,false]`.
+ // Default is `[true, false]`, (i.e. will match if it is signed
+ // or unsigned).
+ // separator: String?
+ // The character used as the thousands separator. Default is no
+ // separator. For more than one symbol use an array, e.g. `[",", ""]`,
+ // makes ',' optional.
+ // groupSize: Number?
+ // group size between separators
+ // groupSize2: Number?
+ // second grouping, where separators 2..n have a different interval than the first separator (for India)
+ this.signed = signed;
+ this.separator = separator;
+ this.groupSize = groupSize;
+ this.groupSize2 = groupSize2;
+}
+=====*/
+
+dojo.number._integerRegexp = function(/*dojo.number.__IntegerRegexpFlags?*/flags){
+ // summary:
+ // Builds a regular expression that matches an integer
+
+ // assign default values to missing parameters
+ flags = flags || {};
+ if(!("signed" in flags)){ flags.signed = [true, false]; }
+ if(!("separator" in flags)){
+ flags.separator = "";
+ }else if(!("groupSize" in flags)){
+ flags.groupSize = 3;
+ }
+
+ var signRE = dojo.regexp.buildGroupRE(flags.signed,
+ function(q){ return q ? "[-+]" : ""; },
+ true
+ );
+
+ var numberRE = dojo.regexp.buildGroupRE(flags.separator,
+ function(sep){
+ if(!sep){
+ return "(?:\\d+)";
+ }
+
+ sep = dojo.regexp.escapeString(sep);
+ if(sep == " "){ sep = "\\s"; }
+ else if(sep == "\xa0"){ sep = "\\s\\xa0"; }
+
+ var grp = flags.groupSize, grp2 = flags.groupSize2;
+ //TODO: should we continue to enforce that numbers with separators begin with 1-9? See #6933
+ if(grp2){
+ var grp2RE = "(?:0|[1-9]\\d{0," + (grp2-1) + "}(?:[" + sep + "]\\d{" + grp2 + "})*[" + sep + "]\\d{" + grp + "})";
+ return ((grp-grp2) > 0) ? "(?:" + grp2RE + "|(?:0|[1-9]\\d{0," + (grp-1) + "}))" : grp2RE;
+ }
+ return "(?:0|[1-9]\\d{0," + (grp-1) + "}(?:[" + sep + "]\\d{" + grp + "})*)";
+ },
+ true
+ );
+
+ return signRE + numberRE; // String
}
-return "(?:0|[1-9]\\d{0,"+(grp-1)+"}(?:["+sep+"]\\d{"+grp+"})*)";
-},true);
-return _46+_47;
-};
+
}