|
1 /*** |
|
2 |
|
3 MochiKit.Format 1.4 |
|
4 |
|
5 See <http://mochikit.com/> for documentation, downloads, license, etc. |
|
6 |
|
7 (c) 2005 Bob Ippolito. All rights Reserved. |
|
8 |
|
9 ***/ |
|
10 |
|
11 if (typeof(dojo) != 'undefined') { |
|
12 dojo.provide('MochiKit.Format'); |
|
13 } |
|
14 |
|
15 if (typeof(MochiKit) == 'undefined') { |
|
16 MochiKit = {}; |
|
17 } |
|
18 |
|
19 if (typeof(MochiKit.Format) == 'undefined') { |
|
20 MochiKit.Format = {}; |
|
21 } |
|
22 |
|
23 MochiKit.Format.NAME = "MochiKit.Format"; |
|
24 MochiKit.Format.VERSION = "1.4"; |
|
25 MochiKit.Format.__repr__ = function () { |
|
26 return "[" + this.NAME + " " + this.VERSION + "]"; |
|
27 }; |
|
28 MochiKit.Format.toString = function () { |
|
29 return this.__repr__(); |
|
30 }; |
|
31 |
|
32 MochiKit.Format._numberFormatter = function (placeholder, header, footer, locale, isPercent, precision, leadingZeros, separatorAt, trailingZeros) { |
|
33 return function (num) { |
|
34 num = parseFloat(num); |
|
35 if (typeof(num) == "undefined" || num === null || isNaN(num)) { |
|
36 return placeholder; |
|
37 } |
|
38 var curheader = header; |
|
39 var curfooter = footer; |
|
40 if (num < 0) { |
|
41 num = -num; |
|
42 } else { |
|
43 curheader = curheader.replace(/-/, ""); |
|
44 } |
|
45 var me = arguments.callee; |
|
46 var fmt = MochiKit.Format.formatLocale(locale); |
|
47 if (isPercent) { |
|
48 num = num * 100.0; |
|
49 curfooter = fmt.percent + curfooter; |
|
50 } |
|
51 num = MochiKit.Format.roundToFixed(num, precision); |
|
52 var parts = num.split(/\./); |
|
53 var whole = parts[0]; |
|
54 var frac = (parts.length == 1) ? "" : parts[1]; |
|
55 var res = ""; |
|
56 while (whole.length < leadingZeros) { |
|
57 whole = "0" + whole; |
|
58 } |
|
59 if (separatorAt) { |
|
60 while (whole.length > separatorAt) { |
|
61 var i = whole.length - separatorAt; |
|
62 //res = res + fmt.separator + whole.substring(i, whole.length); |
|
63 res = fmt.separator + whole.substring(i, whole.length) + res; |
|
64 whole = whole.substring(0, i); |
|
65 } |
|
66 } |
|
67 res = whole + res; |
|
68 if (precision > 0) { |
|
69 while (frac.length < trailingZeros) { |
|
70 frac = frac + "0"; |
|
71 } |
|
72 res = res + fmt.decimal + frac; |
|
73 } |
|
74 return curheader + res + curfooter; |
|
75 }; |
|
76 }; |
|
77 |
|
78 /** @id MochiKit.Format.numberFormatter */ |
|
79 MochiKit.Format.numberFormatter = function (pattern, placeholder/* = "" */, locale/* = "default" */) { |
|
80 // http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html |
|
81 // | 0 | leading or trailing zeros |
|
82 // | # | just the number |
|
83 // | , | separator |
|
84 // | . | decimal separator |
|
85 // | % | Multiply by 100 and format as percent |
|
86 if (typeof(placeholder) == "undefined") { |
|
87 placeholder = ""; |
|
88 } |
|
89 var match = pattern.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/); |
|
90 if (!match) { |
|
91 throw TypeError("Invalid pattern"); |
|
92 } |
|
93 var header = pattern.substr(0, match.index); |
|
94 var footer = pattern.substr(match.index + match[0].length); |
|
95 if (header.search(/-/) == -1) { |
|
96 header = header + "-"; |
|
97 } |
|
98 var whole = match[1]; |
|
99 var frac = (typeof(match[2]) == "string" && match[2] != "") ? match[2] : ""; |
|
100 var isPercent = (typeof(match[3]) == "string" && match[3] != ""); |
|
101 var tmp = whole.split(/,/); |
|
102 var separatorAt; |
|
103 if (typeof(locale) == "undefined") { |
|
104 locale = "default"; |
|
105 } |
|
106 if (tmp.length == 1) { |
|
107 separatorAt = null; |
|
108 } else { |
|
109 separatorAt = tmp[1].length; |
|
110 } |
|
111 var leadingZeros = whole.length - whole.replace(/0/g, "").length; |
|
112 var trailingZeros = frac.length - frac.replace(/0/g, "").length; |
|
113 var precision = frac.length; |
|
114 var rval = MochiKit.Format._numberFormatter( |
|
115 placeholder, header, footer, locale, isPercent, precision, |
|
116 leadingZeros, separatorAt, trailingZeros |
|
117 ); |
|
118 var m = MochiKit.Base; |
|
119 if (m) { |
|
120 var fn = arguments.callee; |
|
121 var args = m.concat(arguments); |
|
122 rval.repr = function () { |
|
123 return [ |
|
124 self.NAME, |
|
125 "(", |
|
126 map(m.repr, args).join(", "), |
|
127 ")" |
|
128 ].join(""); |
|
129 }; |
|
130 } |
|
131 return rval; |
|
132 }; |
|
133 |
|
134 /** @id MochiKit.Format.formatLocale */ |
|
135 MochiKit.Format.formatLocale = function (locale) { |
|
136 if (typeof(locale) == "undefined" || locale === null) { |
|
137 locale = "default"; |
|
138 } |
|
139 if (typeof(locale) == "string") { |
|
140 var rval = MochiKit.Format.LOCALE[locale]; |
|
141 if (typeof(rval) == "string") { |
|
142 rval = arguments.callee(rval); |
|
143 MochiKit.Format.LOCALE[locale] = rval; |
|
144 } |
|
145 return rval; |
|
146 } else { |
|
147 return locale; |
|
148 } |
|
149 }; |
|
150 |
|
151 /** @id MochiKit.Format.twoDigitAverage */ |
|
152 MochiKit.Format.twoDigitAverage = function (numerator, denominator) { |
|
153 if (denominator) { |
|
154 var res = numerator / denominator; |
|
155 if (!isNaN(res)) { |
|
156 return MochiKit.Format.twoDigitFloat(numerator / denominator); |
|
157 } |
|
158 } |
|
159 return "0"; |
|
160 }; |
|
161 |
|
162 /** @id MochiKit.Format.twoDigitFloat */ |
|
163 MochiKit.Format.twoDigitFloat = function (someFloat) { |
|
164 var sign = (someFloat < 0 ? '-' : ''); |
|
165 var s = Math.floor(Math.abs(someFloat) * 100).toString(); |
|
166 if (s == '0') { |
|
167 return s; |
|
168 } |
|
169 if (s.length < 3) { |
|
170 while (s.charAt(s.length - 1) == '0') { |
|
171 s = s.substring(0, s.length - 1); |
|
172 } |
|
173 return sign + '0.' + s; |
|
174 } |
|
175 var head = sign + s.substring(0, s.length - 2); |
|
176 var tail = s.substring(s.length - 2, s.length); |
|
177 if (tail == '00') { |
|
178 return head; |
|
179 } else if (tail.charAt(1) == '0') { |
|
180 return head + '.' + tail.charAt(0); |
|
181 } else { |
|
182 return head + '.' + tail; |
|
183 } |
|
184 }; |
|
185 |
|
186 /** @id MochiKit.Format.lstrip */ |
|
187 MochiKit.Format.lstrip = function (str, /* optional */chars) { |
|
188 str = str + ""; |
|
189 if (typeof(str) != "string") { |
|
190 return null; |
|
191 } |
|
192 if (!chars) { |
|
193 return str.replace(/^\s+/, ""); |
|
194 } else { |
|
195 return str.replace(new RegExp("^[" + chars + "]+"), ""); |
|
196 } |
|
197 }; |
|
198 |
|
199 /** @id MochiKit.Format.rstrip */ |
|
200 MochiKit.Format.rstrip = function (str, /* optional */chars) { |
|
201 str = str + ""; |
|
202 if (typeof(str) != "string") { |
|
203 return null; |
|
204 } |
|
205 if (!chars) { |
|
206 return str.replace(/\s+$/, ""); |
|
207 } else { |
|
208 return str.replace(new RegExp("[" + chars + "]+$"), ""); |
|
209 } |
|
210 }; |
|
211 |
|
212 /** @id MochiKit.Format.strip */ |
|
213 MochiKit.Format.strip = function (str, /* optional */chars) { |
|
214 var self = MochiKit.Format; |
|
215 return self.rstrip(self.lstrip(str, chars), chars); |
|
216 }; |
|
217 |
|
218 /** @id MochiKit.Format.truncToFixed */ |
|
219 MochiKit.Format.truncToFixed = function (aNumber, precision) { |
|
220 aNumber = Math.floor(aNumber * Math.pow(10, precision)); |
|
221 var res = (aNumber * Math.pow(10, -precision)).toFixed(precision); |
|
222 if (res.charAt(0) == ".") { |
|
223 res = "0" + res; |
|
224 } |
|
225 return res; |
|
226 }; |
|
227 |
|
228 /** @id MochiKit.Format.roundToFixed */ |
|
229 MochiKit.Format.roundToFixed = function (aNumber, precision) { |
|
230 return MochiKit.Format.truncToFixed( |
|
231 aNumber + 0.5 * Math.pow(10, -precision), |
|
232 precision |
|
233 ); |
|
234 }; |
|
235 |
|
236 /** @id MochiKit.Format.percentFormat */ |
|
237 MochiKit.Format.percentFormat = function (someFloat) { |
|
238 return MochiKit.Format.twoDigitFloat(100 * someFloat) + '%'; |
|
239 }; |
|
240 |
|
241 MochiKit.Format.EXPORT = [ |
|
242 "truncToFixed", |
|
243 "roundToFixed", |
|
244 "numberFormatter", |
|
245 "formatLocale", |
|
246 "twoDigitAverage", |
|
247 "twoDigitFloat", |
|
248 "percentFormat", |
|
249 "lstrip", |
|
250 "rstrip", |
|
251 "strip" |
|
252 ]; |
|
253 |
|
254 MochiKit.Format.LOCALE = { |
|
255 en_US: {separator: ",", decimal: ".", percent: "%"}, |
|
256 de_DE: {separator: ".", decimal: ",", percent: "%"}, |
|
257 fr_FR: {separator: " ", decimal: ",", percent: "%"}, |
|
258 "default": "en_US" |
|
259 }; |
|
260 |
|
261 MochiKit.Format.EXPORT_OK = []; |
|
262 MochiKit.Format.EXPORT_TAGS = { |
|
263 ':all': MochiKit.Format.EXPORT, |
|
264 ':common': MochiKit.Format.EXPORT |
|
265 }; |
|
266 |
|
267 MochiKit.Format.__new__ = function () { |
|
268 // MochiKit.Base.nameFunctions(this); |
|
269 var base = this.NAME + "."; |
|
270 var k, v, o; |
|
271 for (k in this.LOCALE) { |
|
272 o = this.LOCALE[k]; |
|
273 if (typeof(o) == "object") { |
|
274 o.repr = function () { return this.NAME; }; |
|
275 o.NAME = base + "LOCALE." + k; |
|
276 } |
|
277 } |
|
278 for (k in this) { |
|
279 o = this[k]; |
|
280 if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') { |
|
281 try { |
|
282 o.NAME = base + k; |
|
283 } catch (e) { |
|
284 // pass |
|
285 } |
|
286 } |
|
287 } |
|
288 }; |
|
289 |
|
290 MochiKit.Format.__new__(); |
|
291 |
|
292 if (typeof(MochiKit.Base) != "undefined") { |
|
293 MochiKit.Base._exportSymbols(this, MochiKit.Format); |
|
294 } else { |
|
295 (function (globals, module) { |
|
296 if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined') |
|
297 || (MochiKit.__export__ === false)) { |
|
298 var all = module.EXPORT_TAGS[":all"]; |
|
299 for (var i = 0; i < all.length; i++) { |
|
300 globals[all[i]] = module[all[i]]; |
|
301 } |
|
302 } |
|
303 })(this, MochiKit.Format); |
|
304 } |