2150 |
mathias |
1 |
if(!dojo._hasResource["dojo.number"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
|
|
|
2 |
dojo._hasResource["dojo.number"] = true;
|
|
|
3 |
dojo.provide("dojo.number");
|
|
|
4 |
|
|
|
5 |
dojo.require("dojo.i18n");
|
|
|
6 |
dojo.requireLocalization("dojo.cldr", "number", null, "zh-cn,en,en-ca,zh-tw,en-us,it,ja-jp,ROOT,de-de,es-es,fr,pt,ko-kr,es,de");
|
|
|
7 |
dojo.require("dojo.string");
|
|
|
8 |
dojo.require("dojo.regexp");
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
/*=====
|
|
|
12 |
dojo.number.__formatOptions = function(kwArgs){
|
|
|
13 |
// pattern: String?
|
|
|
14 |
// override formatting pattern with this string (see
|
|
|
15 |
// dojo.number._applyPattern)
|
|
|
16 |
// type: String?
|
|
|
17 |
// choose a format type based on the locale from the following:
|
|
|
18 |
// decimal, scientific, percent, currency. decimal by default.
|
|
|
19 |
// places: Number?
|
|
|
20 |
// fixed number of decimal places to show. This overrides any
|
|
|
21 |
// information in the provided pattern.
|
|
|
22 |
// round: NUmber?
|
|
|
23 |
// 5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
|
|
|
24 |
// means don't round.
|
|
|
25 |
// currency: String?
|
|
|
26 |
// iso4217 currency code
|
|
|
27 |
// symbol: String?
|
|
|
28 |
// localized currency symbol
|
|
|
29 |
// locale: String?
|
|
|
30 |
// override the locale used to determine formatting rules
|
|
|
31 |
}
|
|
|
32 |
=====*/
|
|
|
33 |
|
|
|
34 |
dojo.number.format = function(/*Number*/value, /*dojo.number.__formatOptions?*/options){
|
|
|
35 |
// summary:
|
|
|
36 |
// Format a Number as a String, using locale-specific settings
|
|
|
37 |
// description:
|
|
|
38 |
// Create a string from a Number using a known localized pattern.
|
|
|
39 |
// Formatting patterns appropriate to the locale are chosen from the
|
|
|
40 |
// CLDR http://unicode.org/cldr as well as the appropriate symbols and
|
|
|
41 |
// delimiters. See http://www.unicode.org/reports/tr35/#Number_Elements
|
|
|
42 |
// value:
|
|
|
43 |
// the number to be formatted. If not a valid JavaScript number,
|
|
|
44 |
// return null.
|
|
|
45 |
|
|
|
46 |
options = dojo.mixin({}, options || {});
|
|
|
47 |
var locale = dojo.i18n.normalizeLocale(options.locale);
|
|
|
48 |
var bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale);
|
|
|
49 |
options.customs = bundle;
|
|
|
50 |
var pattern = options.pattern || bundle[(options.type || "decimal") + "Format"];
|
|
|
51 |
if(isNaN(value)){ return null; } // null
|
|
|
52 |
return dojo.number._applyPattern(value, pattern, options); // String
|
|
|
53 |
};
|
|
|
54 |
|
|
|
55 |
//dojo.number._numberPatternRE = /(?:[#0]*,?)*[#0](?:\.0*#*)?/; // not precise, but good enough
|
|
|
56 |
dojo.number._numberPatternRE = /[#0,]*[#0](?:\.0*#*)?/; // not precise, but good enough
|
|
|
57 |
|
|
|
58 |
dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.number.__formatOptions?*/options){
|
|
|
59 |
// summary:
|
|
|
60 |
// Apply pattern to format value as a string using options. Gives no
|
|
|
61 |
// consideration to local customs.
|
|
|
62 |
// value:
|
|
|
63 |
// the number to be formatted.
|
|
|
64 |
// pattern:
|
|
|
65 |
// a pattern string as described in
|
|
|
66 |
// http://www.unicode.org/reports/tr35/#Number_Format_Patterns
|
|
|
67 |
// options: dojo.number.__formatOptions?
|
|
|
68 |
// _applyPattern is usually called via dojo.number.format() which
|
|
|
69 |
// populates an extra property in the options parameter, "customs".
|
|
|
70 |
// The customs object specifies group and decimal parameters if set.
|
|
|
71 |
|
|
|
72 |
//TODO: support escapes
|
|
|
73 |
options = options || {};
|
|
|
74 |
var group = options.customs.group;
|
|
|
75 |
var decimal = options.customs.decimal;
|
|
|
76 |
|
|
|
77 |
var patternList = pattern.split(';');
|
|
|
78 |
var positivePattern = patternList[0];
|
|
|
79 |
pattern = patternList[(value < 0) ? 1 : 0] || ("-" + positivePattern);
|
|
|
80 |
|
|
|
81 |
//TODO: only test against unescaped
|
|
|
82 |
if(pattern.indexOf('%') != -1){
|
|
|
83 |
value *= 100;
|
|
|
84 |
}else if(pattern.indexOf('\u2030') != -1){
|
|
|
85 |
value *= 1000; // per mille
|
|
|
86 |
}else if(pattern.indexOf('\u00a4') != -1){
|
|
|
87 |
group = options.customs.currencyGroup || group;//mixins instead?
|
|
|
88 |
decimal = options.customs.currencyDecimal || decimal;// Should these be mixins instead?
|
|
|
89 |
pattern = pattern.replace(/\u00a4{1,3}/, function(match){
|
|
|
90 |
var prop = ["symbol", "currency", "displayName"][match.length-1];
|
|
|
91 |
return options[prop] || options.currency || "";
|
|
|
92 |
});
|
|
|
93 |
}else if(pattern.indexOf('E') != -1){
|
|
|
94 |
throw new Error("exponential notation not supported");
|
|
|
95 |
}
|
|
|
96 |
|
|
|
97 |
//TODO: support @ sig figs?
|
|
|
98 |
var numberPatternRE = dojo.number._numberPatternRE;
|
|
|
99 |
var numberPattern = positivePattern.match(numberPatternRE);
|
|
|
100 |
if(!numberPattern){
|
|
|
101 |
throw new Error("unable to find a number expression in pattern: "+pattern);
|
|
|
102 |
}
|
|
|
103 |
return pattern.replace(numberPatternRE,
|
|
|
104 |
dojo.number._formatAbsolute(value, numberPattern[0], {decimal: decimal, group: group, places: options.places}));
|
|
|
105 |
}
|
|
|
106 |
|
|
|
107 |
dojo.number.round = function(/*Number*/value, /*Number*/places, /*Number?*/multiple){
|
|
|
108 |
// summary:
|
|
|
109 |
// Rounds the number at the given number of places
|
|
|
110 |
// value:
|
|
|
111 |
// the number to round
|
|
|
112 |
// places:
|
|
|
113 |
// the number of decimal places where rounding takes place
|
|
|
114 |
// multiple:
|
|
|
115 |
// rounds next place to nearest multiple
|
|
|
116 |
|
|
|
117 |
var pieces = String(value).split(".");
|
|
|
118 |
var length = (pieces[1] && pieces[1].length) || 0;
|
|
|
119 |
if(length > places){
|
|
|
120 |
var factor = Math.pow(10, places);
|
|
|
121 |
if(multiple > 0){factor *= 10/multiple;places++;} //FIXME
|
|
|
122 |
value = Math.round(value * factor)/factor;
|
|
|
123 |
|
|
|
124 |
// truncate to remove any residual floating point values
|
|
|
125 |
pieces = String(value).split(".");
|
|
|
126 |
length = (pieces[1] && pieces[1].length) || 0;
|
|
|
127 |
if(length > places){
|
|
|
128 |
pieces[1] = pieces[1].substr(0, places);
|
|
|
129 |
value = Number(pieces.join("."));
|
|
|
130 |
}
|
|
|
131 |
}
|
|
|
132 |
return value; //Number
|
|
|
133 |
}
|
|
|
134 |
|
|
|
135 |
/*=====
|
|
|
136 |
dojo.number.__formatAbsoluteOptions = function(kwArgs){
|
|
|
137 |
// decimal: String?
|
|
|
138 |
// the decimal separator
|
|
|
139 |
// group: String?
|
|
|
140 |
// the group separator
|
|
|
141 |
// places: Integer?
|
|
|
142 |
// number of decimal places
|
|
|
143 |
// round: Number?
|
|
|
144 |
// 5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
|
|
|
145 |
// means don't round.
|
|
|
146 |
}
|
|
|
147 |
=====*/
|
|
|
148 |
|
|
|
149 |
dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*dojo.number.__formatAbsoluteOptions?*/options){
|
|
|
150 |
// summary:
|
|
|
151 |
// Apply numeric pattern to absolute value using options. Gives no
|
|
|
152 |
// consideration to local customs.
|
|
|
153 |
// value:
|
|
|
154 |
// the number to be formatted, ignores sign
|
|
|
155 |
// pattern:
|
|
|
156 |
// the number portion of a pattern (e.g. #,##0.00)
|
|
|
157 |
options = options || {};
|
|
|
158 |
if(options.places === true){options.places=0;}
|
|
|
159 |
if(options.places === Infinity){options.places=6;} // avoid a loop; pick a limit
|
|
|
160 |
|
|
|
161 |
var patternParts = pattern.split(".");
|
|
|
162 |
var maxPlaces = (options.places >= 0) ? options.places : (patternParts[1] && patternParts[1].length) || 0;
|
|
|
163 |
if(!(options.round < 0)){
|
|
|
164 |
value = dojo.number.round(value, maxPlaces, options.round);
|
|
|
165 |
}
|
|
|
166 |
|
|
|
167 |
var valueParts = String(Math.abs(value)).split(".");
|
|
|
168 |
var fractional = valueParts[1] || "";
|
|
|
169 |
if(options.places){
|
|
|
170 |
valueParts[1] = dojo.string.pad(fractional.substr(0, options.places), options.places, '0', true);
|
|
|
171 |
}else if(patternParts[1] && options.places !== 0){
|
|
|
172 |
// Pad fractional with trailing zeros
|
|
|
173 |
var pad = patternParts[1].lastIndexOf("0") + 1;
|
|
|
174 |
if(pad > fractional.length){
|
|
|
175 |
valueParts[1] = dojo.string.pad(fractional, pad, '0', true);
|
|
|
176 |
}
|
|
|
177 |
|
|
|
178 |
// Truncate fractional
|
|
|
179 |
var places = patternParts[1].length;
|
|
|
180 |
if(places < fractional.length){
|
|
|
181 |
valueParts[1] = fractional.substr(0, places);
|
|
|
182 |
}
|
|
|
183 |
}else{
|
|
|
184 |
if(valueParts[1]){ valueParts.pop(); }
|
|
|
185 |
}
|
|
|
186 |
|
|
|
187 |
// Pad whole with leading zeros
|
|
|
188 |
var patternDigits = patternParts[0].replace(',', '');
|
|
|
189 |
pad = patternDigits.indexOf("0");
|
|
|
190 |
if(pad != -1){
|
|
|
191 |
pad = patternDigits.length - pad;
|
|
|
192 |
if(pad > valueParts[0].length){
|
|
|
193 |
valueParts[0] = dojo.string.pad(valueParts[0], pad);
|
|
|
194 |
}
|
|
|
195 |
|
|
|
196 |
// Truncate whole
|
|
|
197 |
if(patternDigits.indexOf("#") == -1){
|
|
|
198 |
valueParts[0] = valueParts[0].substr(valueParts[0].length - pad);
|
|
|
199 |
}
|
|
|
200 |
}
|
|
|
201 |
|
|
|
202 |
// Add group separators
|
|
|
203 |
var index = patternParts[0].lastIndexOf(',');
|
|
|
204 |
var groupSize, groupSize2;
|
|
|
205 |
if(index != -1){
|
|
|
206 |
groupSize = patternParts[0].length - index - 1;
|
|
|
207 |
var remainder = patternParts[0].substr(0, index);
|
|
|
208 |
index = remainder.lastIndexOf(',');
|
|
|
209 |
if(index != -1){
|
|
|
210 |
groupSize2 = remainder.length - index - 1;
|
|
|
211 |
}
|
|
|
212 |
}
|
|
|
213 |
var pieces = [];
|
|
|
214 |
for(var whole = valueParts[0]; whole;){
|
|
|
215 |
var off = whole.length - groupSize;
|
|
|
216 |
pieces.push((off > 0) ? whole.substr(off) : whole);
|
|
|
217 |
whole = (off > 0) ? whole.slice(0, off) : "";
|
|
|
218 |
if(groupSize2){
|
|
|
219 |
groupSize = groupSize2;
|
|
|
220 |
delete groupSize2;
|
|
|
221 |
}
|
|
|
222 |
}
|
|
|
223 |
valueParts[0] = pieces.reverse().join(options.group || ",");
|
|
|
224 |
|
|
|
225 |
return valueParts.join(options.decimal || ".");
|
|
|
226 |
};
|
|
|
227 |
|
|
|
228 |
/*=====
|
|
|
229 |
dojo.number.__regexpOptions = function(kwArgs){
|
|
|
230 |
// pattern: String?
|
|
|
231 |
// override pattern with this string. Default is provided based on
|
|
|
232 |
// locale.
|
|
|
233 |
// type: String?
|
|
|
234 |
// choose a format type based on the locale from the following:
|
|
|
235 |
// decimal, scientific, percent, currency. decimal by default.
|
|
|
236 |
// locale: String?
|
|
|
237 |
// override the locale used to determine formatting rules
|
|
|
238 |
// strict: Boolean?
|
|
|
239 |
// strict parsing, false by default
|
|
|
240 |
// places: Number|String?
|
|
|
241 |
// number of decimal places to accept: Infinity, a positive number, or
|
|
|
242 |
// a range "n,m". By default, defined by pattern.
|
|
|
243 |
}
|
|
|
244 |
=====*/
|
|
|
245 |
dojo.number.regexp = function(/*dojo.number.__regexpOptions?*/options){
|
|
|
246 |
// summary:
|
|
|
247 |
// Builds the regular needed to parse a number
|
|
|
248 |
// description:
|
|
|
249 |
// Returns regular expression with positive and negative match, group
|
|
|
250 |
// and decimal separators
|
|
|
251 |
return dojo.number._parseInfo(options).regexp; // String
|
|
|
252 |
}
|
|
|
253 |
|
|
|
254 |
dojo.number._parseInfo = function(/*Object?*/options){
|
|
|
255 |
options = options || {};
|
|
|
256 |
var locale = dojo.i18n.normalizeLocale(options.locale);
|
|
|
257 |
var bundle = dojo.i18n.getLocalization("dojo.cldr", "number", locale);
|
|
|
258 |
var pattern = options.pattern || bundle[(options.type || "decimal") + "Format"];
|
|
|
259 |
//TODO: memoize?
|
|
|
260 |
var group = bundle.group;
|
|
|
261 |
var decimal = bundle.decimal;
|
|
|
262 |
var factor = 1;
|
|
|
263 |
|
|
|
264 |
if(pattern.indexOf('%') != -1){
|
|
|
265 |
factor /= 100;
|
|
|
266 |
}else if(pattern.indexOf('\u2030') != -1){
|
|
|
267 |
factor /= 1000; // per mille
|
|
|
268 |
}else{
|
|
|
269 |
var isCurrency = pattern.indexOf('\u00a4') != -1;
|
|
|
270 |
if(isCurrency){
|
|
|
271 |
group = bundle.currencyGroup || group;
|
|
|
272 |
decimal = bundle.currencyDecimal || decimal;
|
|
|
273 |
}
|
|
|
274 |
}
|
|
|
275 |
|
|
|
276 |
//TODO: handle quoted escapes
|
|
|
277 |
var patternList = pattern.split(';');
|
|
|
278 |
if(patternList.length == 1){
|
|
|
279 |
patternList.push("-" + patternList[0]);
|
|
|
280 |
}
|
|
|
281 |
|
|
|
282 |
var re = dojo.regexp.buildGroupRE(patternList, function(pattern){
|
|
|
283 |
pattern = "(?:"+dojo.regexp.escapeString(pattern, '.')+")";
|
|
|
284 |
return pattern.replace(dojo.number._numberPatternRE, function(format){
|
|
|
285 |
var flags = {
|
|
|
286 |
signed: false,
|
|
|
287 |
separator: options.strict ? group : [group,""],
|
|
|
288 |
fractional: options.fractional,
|
|
|
289 |
decimal: decimal,
|
|
|
290 |
exponent: false};
|
|
|
291 |
var parts = format.split('.');
|
|
|
292 |
var places = options.places;
|
|
|
293 |
if(parts.length == 1 || places === 0){flags.fractional = false;}
|
|
|
294 |
else{
|
|
|
295 |
if(typeof places == "undefined"){ places = parts[1].lastIndexOf('0')+1; }
|
|
|
296 |
if(places && options.fractional == undefined){flags.fractional = true;} // required fractional, unless otherwise specified
|
|
|
297 |
if(!options.places && (places < parts[1].length)){ places += "," + parts[1].length; }
|
|
|
298 |
flags.places = places;
|
|
|
299 |
}
|
|
|
300 |
var groups = parts[0].split(',');
|
|
|
301 |
if(groups.length>1){
|
|
|
302 |
flags.groupSize = groups.pop().length;
|
|
|
303 |
if(groups.length>1){
|
|
|
304 |
flags.groupSize2 = groups.pop().length;
|
|
|
305 |
}
|
|
|
306 |
}
|
|
|
307 |
return "("+dojo.number._realNumberRegexp(flags)+")";
|
|
|
308 |
});
|
|
|
309 |
}, true);
|
|
|
310 |
|
|
|
311 |
if(isCurrency){
|
|
|
312 |
// substitute the currency symbol for the placeholder in the pattern
|
|
|
313 |
re = re.replace(/(\s*)(\u00a4{1,3})(\s*)/g, function(match, before, target, after){
|
|
|
314 |
var prop = ["symbol", "currency", "displayName"][target.length-1];
|
|
|
315 |
var symbol = dojo.regexp.escapeString(options[prop] || options.currency || "");
|
|
|
316 |
before = before ? "\\s" : "";
|
|
|
317 |
after = after ? "\\s" : "";
|
|
|
318 |
if(!options.strict){
|
|
|
319 |
if(before){before += "*";}
|
|
|
320 |
if(after){after += "*";}
|
|
|
321 |
return "(?:"+before+symbol+after+")?";
|
|
|
322 |
}
|
|
|
323 |
return before+symbol+after;
|
|
|
324 |
});
|
|
|
325 |
}
|
|
|
326 |
|
|
|
327 |
//TODO: substitute localized sign/percent/permille/etc.?
|
|
|
328 |
|
|
|
329 |
// normalize whitespace and return
|
|
|
330 |
return {regexp: re.replace(/[\xa0 ]/g, "[\\s\\xa0]"), group: group, decimal: decimal, factor: factor}; // Object
|
|
|
331 |
}
|
|
|
332 |
|
|
|
333 |
/*=====
|
|
|
334 |
dojo.number.__parseOptions = function(kwArgs){
|
|
|
335 |
// pattern: String
|
|
|
336 |
// override pattern with this string. Default is provided based on
|
|
|
337 |
// locale.
|
|
|
338 |
// type: String?
|
|
|
339 |
// choose a format type based on the locale from the following:
|
|
|
340 |
// decimal, scientific, percent, currency. decimal by default.
|
|
|
341 |
// locale: String
|
|
|
342 |
// override the locale used to determine formatting rules
|
|
|
343 |
// strict: Boolean?
|
|
|
344 |
// strict parsing, false by default
|
|
|
345 |
// currency: Object
|
|
|
346 |
// object with currency information
|
|
|
347 |
}
|
|
|
348 |
=====*/
|
|
|
349 |
dojo.number.parse = function(/*String*/expression, /*dojo.number.__parseOptions?*/options){
|
|
|
350 |
// summary:
|
|
|
351 |
// Convert a properly formatted string to a primitive Number, using
|
|
|
352 |
// locale-specific settings.
|
|
|
353 |
// description:
|
|
|
354 |
// Create a Number from a string using a known localized pattern.
|
|
|
355 |
// Formatting patterns are chosen appropriate to the locale.
|
|
|
356 |
// Formatting patterns are implemented using the syntax described at
|
|
|
357 |
// *URL*
|
|
|
358 |
// expression:
|
|
|
359 |
// A string representation of a Number
|
|
|
360 |
var info = dojo.number._parseInfo(options);
|
|
|
361 |
var results = (new RegExp("^"+info.regexp+"$")).exec(expression);
|
|
|
362 |
if(!results){
|
|
|
363 |
return NaN; //NaN
|
|
|
364 |
}
|
|
|
365 |
var absoluteMatch = results[1]; // match for the positive expression
|
|
|
366 |
if(!results[1]){
|
|
|
367 |
if(!results[2]){
|
|
|
368 |
return NaN; //NaN
|
|
|
369 |
}
|
|
|
370 |
// matched the negative pattern
|
|
|
371 |
absoluteMatch =results[2];
|
|
|
372 |
info.factor *= -1;
|
|
|
373 |
}
|
|
|
374 |
|
|
|
375 |
// Transform it to something Javascript can parse as a number. Normalize
|
|
|
376 |
// decimal point and strip out group separators or alternate forms of whitespace
|
|
|
377 |
absoluteMatch = absoluteMatch.
|
|
|
378 |
replace(new RegExp("["+info.group + "\\s\\xa0"+"]", "g"), "").
|
|
|
379 |
replace(info.decimal, ".");
|
|
|
380 |
// Adjust for negative sign, percent, etc. as necessary
|
|
|
381 |
return Number(absoluteMatch) * info.factor; //Number
|
|
|
382 |
};
|
|
|
383 |
|
|
|
384 |
/*=====
|
|
|
385 |
dojo.number.__realNumberRegexpFlags = function(kwArgs){
|
|
|
386 |
// places: Number?
|
|
|
387 |
// The integer number of decimal places or a range given as "n,m". If
|
|
|
388 |
// not given, the decimal part is optional and the number of places is
|
|
|
389 |
// unlimited.
|
|
|
390 |
// decimal: String?
|
|
|
391 |
// A string for the character used as the decimal point. Default
|
|
|
392 |
// is ".".
|
|
|
393 |
// fractional: Boolean|Array?
|
|
|
394 |
// Whether decimal places are allowed. Can be true, false, or [true,
|
|
|
395 |
// false]. Default is [true, false]
|
|
|
396 |
// exponent: Boolean|Array?
|
|
|
397 |
// Express in exponential notation. Can be true, false, or [true,
|
|
|
398 |
// false]. Default is [true, false], (i.e. will match if the
|
|
|
399 |
// exponential part is present are not).
|
|
|
400 |
// eSigned: Boolean|Array?
|
|
|
401 |
// The leading plus-or-minus sign on the exponent. Can be true,
|
|
|
402 |
// false, or [true, false]. Default is [true, false], (i.e. will
|
|
|
403 |
// match if it is signed or unsigned). flags in regexp.integer can be
|
|
|
404 |
// applied.
|
|
|
405 |
}
|
|
|
406 |
=====*/
|
|
|
407 |
|
|
|
408 |
dojo.number._realNumberRegexp = function(/*dojo.number.__realNumberRegexpFlags?*/flags){
|
|
|
409 |
// summary:
|
|
|
410 |
// Builds a regular expression to match a real number in exponential
|
|
|
411 |
// notation
|
|
|
412 |
// flags:
|
|
|
413 |
// An object
|
|
|
414 |
|
|
|
415 |
// assign default values to missing paramters
|
|
|
416 |
flags = flags || {};
|
|
|
417 |
if(typeof flags.places == "undefined"){ flags.places = Infinity; }
|
|
|
418 |
if(typeof flags.decimal != "string"){ flags.decimal = "."; }
|
|
|
419 |
if(typeof flags.fractional == "undefined" || /^0/.test(flags.places)){ flags.fractional = [true, false]; }
|
|
|
420 |
if(typeof flags.exponent == "undefined"){ flags.exponent = [true, false]; }
|
|
|
421 |
if(typeof flags.eSigned == "undefined"){ flags.eSigned = [true, false]; }
|
|
|
422 |
|
|
|
423 |
// integer RE
|
|
|
424 |
var integerRE = dojo.number._integerRegexp(flags);
|
|
|
425 |
|
|
|
426 |
// decimal RE
|
|
|
427 |
var decimalRE = dojo.regexp.buildGroupRE(flags.fractional,
|
|
|
428 |
function(q){
|
|
|
429 |
var re = "";
|
|
|
430 |
if(q && (flags.places!==0)){
|
|
|
431 |
re = "\\" + flags.decimal;
|
|
|
432 |
if(flags.places == Infinity){
|
|
|
433 |
re = "(?:" + re + "\\d+)?";
|
|
|
434 |
}else{
|
|
|
435 |
re += "\\d{" + flags.places + "}";
|
|
|
436 |
}
|
|
|
437 |
}
|
|
|
438 |
return re;
|
|
|
439 |
},
|
|
|
440 |
true
|
|
|
441 |
);
|
|
|
442 |
|
|
|
443 |
// exponent RE
|
|
|
444 |
var exponentRE = dojo.regexp.buildGroupRE(flags.exponent,
|
|
|
445 |
function(q){
|
|
|
446 |
if(q){ return "([eE]" + dojo.number._integerRegexp({ signed: flags.eSigned}) + ")"; }
|
|
|
447 |
return "";
|
|
|
448 |
}
|
|
|
449 |
);
|
|
|
450 |
|
|
|
451 |
// real number RE
|
|
|
452 |
var realRE = integerRE + decimalRE;
|
|
|
453 |
// allow for decimals without integers, e.g. .25
|
|
|
454 |
if(decimalRE){realRE = "(?:(?:"+ realRE + ")|(?:" + decimalRE + "))";}
|
|
|
455 |
return realRE + exponentRE; // String
|
|
|
456 |
};
|
|
|
457 |
|
|
|
458 |
/*=====
|
|
|
459 |
dojo.number.__integerRegexpFlags = function(kwArgs){
|
|
|
460 |
// signed: Boolean?
|
|
|
461 |
// The leading plus-or-minus sign. Can be true, false, or [true,
|
|
|
462 |
// false]. Default is [true, false], (i.e. will match if it is signed
|
|
|
463 |
// or unsigned).
|
|
|
464 |
// separator: String?
|
|
|
465 |
// The character used as the thousands separator. Default is no
|
|
|
466 |
// separator. For more than one symbol use an array, e.g. [",", ""],
|
|
|
467 |
// makes ',' optional.
|
|
|
468 |
// groupSize: Number?
|
|
|
469 |
// group size between separators
|
|
|
470 |
// flags.groupSize2: Number?
|
|
|
471 |
// second grouping (for India)
|
|
|
472 |
}
|
|
|
473 |
=====*/
|
|
|
474 |
|
|
|
475 |
dojo.number._integerRegexp = function(/*dojo.number.__integerRegexpFlags?*/flags){
|
|
|
476 |
// summary:
|
|
|
477 |
// Builds a regular expression that matches an integer
|
|
|
478 |
// flags:
|
|
|
479 |
// An object
|
|
|
480 |
|
|
|
481 |
// assign default values to missing paramters
|
|
|
482 |
flags = flags || {};
|
|
|
483 |
if(typeof flags.signed == "undefined"){ flags.signed = [true, false]; }
|
|
|
484 |
if(typeof flags.separator == "undefined"){
|
|
|
485 |
flags.separator = "";
|
|
|
486 |
}else if(typeof flags.groupSize == "undefined"){
|
|
|
487 |
flags.groupSize = 3;
|
|
|
488 |
}
|
|
|
489 |
// build sign RE
|
|
|
490 |
var signRE = dojo.regexp.buildGroupRE(flags.signed,
|
|
|
491 |
function(q) { return q ? "[-+]" : ""; },
|
|
|
492 |
true
|
|
|
493 |
);
|
|
|
494 |
|
|
|
495 |
// number RE
|
|
|
496 |
var numberRE = dojo.regexp.buildGroupRE(flags.separator,
|
|
|
497 |
function(sep){
|
|
|
498 |
if(!sep){
|
|
|
499 |
return "(?:0|[1-9]\\d*)";
|
|
|
500 |
}
|
|
|
501 |
|
|
|
502 |
sep = dojo.regexp.escapeString(sep);
|
|
|
503 |
if(sep == " "){ sep = "\\s"; }
|
|
|
504 |
else if(sep == "\xa0"){ sep = "\\s\\xa0"; }
|
|
|
505 |
|
|
|
506 |
var grp = flags.groupSize, grp2 = flags.groupSize2;
|
|
|
507 |
if(grp2){
|
|
|
508 |
var grp2RE = "(?:0|[1-9]\\d{0," + (grp2-1) + "}(?:[" + sep + "]\\d{" + grp2 + "})*[" + sep + "]\\d{" + grp + "})";
|
|
|
509 |
return ((grp-grp2) > 0) ? "(?:" + grp2RE + "|(?:0|[1-9]\\d{0," + (grp-1) + "}))" : grp2RE;
|
|
|
510 |
}
|
|
|
511 |
return "(?:0|[1-9]\\d{0," + (grp-1) + "}(?:[" + sep + "]\\d{" + grp + "})*)";
|
|
|
512 |
},
|
|
|
513 |
true
|
|
|
514 |
);
|
|
|
515 |
|
|
|
516 |
// integer RE
|
|
|
517 |
return signRE + numberRE; // String
|
|
|
518 |
}
|
|
|
519 |
|
|
|
520 |
}
|