Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/extensions/i18n/number-format.js

Issue 23622028: Snapshot i18n Javascript code (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/extensions/i18n/locale.js ('k') | src/extensions/i18n/overrides.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 // limitations under the License.
28
29 // ECMAScript 402 API implementation is broken into separate files for
30 // each service. The build system combines them together into one
31 // Intl namespace.
32
33 /**
34 * Verifies that the input is a well-formed ISO 4217 currency code.
35 * Don't uppercase to test. It could convert invalid code into a valid one.
36 * For example \u00DFP (Eszett+P) becomes SSP.
37 */
38 function isWellFormedCurrencyCode(currency) {
39 return typeof currency == "string" &&
40 currency.length == 3 &&
41 currency.match(/[^A-Za-z]/) == null;
42 }
43
44
45 /**
46 * Returns the valid digit count for a property, or throws RangeError on
47 * a value out of the range.
48 */
49 function getNumberOption(options, property, min, max, fallback) {
50 var value = options[property];
51 if (value !== undefined) {
52 value = Number(value);
53 if (isNaN(value) || value < min || value > max) {
54 throw new RangeError(property + ' value is out of range.');
55 }
56 return Math.floor(value);
57 }
58
59 return fallback;
60 }
61
62
63 /**
64 * Initializes the given object so it's a valid NumberFormat instance.
65 * Useful for subclassing.
66 */
67 function initializeNumberFormat(numberFormat, locales, options) {
68 if (numberFormat.hasOwnProperty('__initializedIntlObject')) {
69 throw new TypeError('Trying to re-initialize NumberFormat object.');
70 }
71
72 if (options === undefined) {
73 options = {};
74 }
75
76 var getOption = getGetOption(options, 'numberformat');
77
78 var locale = resolveLocale('numberformat', locales, options);
79
80 var internalOptions = {};
81 defineWEProperty(internalOptions, 'style', getOption(
82 'style', 'string', ['decimal', 'percent', 'currency'], 'decimal'));
83
84 var currency = getOption('currency', 'string');
85 if (currency !== undefined && !isWellFormedCurrencyCode(currency)) {
86 throw new RangeError('Invalid currency code: ' + currency);
87 }
88
89 if (internalOptions.style === 'currency' && currency === undefined) {
90 throw new TypeError('Currency code is required with currency style.');
91 }
92
93 var currencyDisplay = getOption(
94 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
95 if (internalOptions.style === 'currency') {
96 defineWEProperty(internalOptions, 'currency', currency.toUpperCase());
97 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay);
98 }
99
100 // Digit ranges.
101 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
102 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
103
104 var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
105 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
106
107 var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, 3);
108 defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
109
110 var mnsd = options['minimumSignificantDigits'];
111 var mxsd = options['maximumSignificantDigits'];
112 if (mnsd !== undefined || mxsd !== undefined) {
113 mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 0);
114 defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
115
116 mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
117 defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
118 }
119
120 // Grouping.
121 defineWEProperty(internalOptions, 'useGrouping', getOption(
122 'useGrouping', 'boolean', undefined, true));
123
124 // ICU prefers options to be passed using -u- extension key/values for
125 // number format, so we need to build that.
126 var extensionMap = parseExtension(locale.extension);
127 var extension = setOptions(options, extensionMap, NUMBER_FORMAT_KEY_MAP,
128 getOption, internalOptions);
129
130 var requestedLocale = locale.locale + extension;
131 var resolved = Object.defineProperties({}, {
132 currency: {writable: true},
133 currencyDisplay: {writable: true},
134 locale: {writable: true},
135 maximumFractionDigits: {writable: true},
136 minimumFractionDigits: {writable: true},
137 minimumIntegerDigits: {writable: true},
138 numberingSystem: {writable: true},
139 requestedLocale: {value: requestedLocale, writable: true},
140 style: {value: internalOptions.style, writable: true},
141 useGrouping: {writable: true}
142 });
143 if (internalOptions.hasOwnProperty('minimumSignificantDigits')) {
144 defineWEProperty(resolved, 'minimumSignificantDigits', undefined);
145 }
146 if (internalOptions.hasOwnProperty('maximumSignificantDigits')) {
147 defineWEProperty(resolved, 'maximumSignificantDigits', undefined);
148 }
149 var formatter = %CreateNumberFormat(requestedLocale,
150 internalOptions,
151 resolved);
152
153 // We can't get information about number or currency style from ICU, so we
154 // assume user request was fulfilled.
155 if (internalOptions.style === 'currency') {
156 Object.defineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
157 writable: true});
158 }
159
160 Object.defineProperty(numberFormat, 'formatter', {value: formatter});
161 Object.defineProperty(numberFormat, 'resolved', {value: resolved});
162 Object.defineProperty(numberFormat, '__initializedIntlObject',
163 {value: 'numberformat'});
164
165 return numberFormat;
166 }
167
168
169 /**
170 * Constructs Intl.NumberFormat object given optional locales and options
171 * parameters.
172 *
173 * @constructor
174 */
175 %SetProperty(Intl, 'NumberFormat', function() {
176 var locales = arguments[0];
177 var options = arguments[1];
178
179 if (!this || this === Intl) {
180 // Constructor is called as a function.
181 return new Intl.NumberFormat(locales, options);
182 }
183
184 return initializeNumberFormat(toObject(this), locales, options);
185 },
186 ATTRIBUTES.DONT_ENUM
187 );
188
189
190 /**
191 * NumberFormat resolvedOptions method.
192 */
193 %SetProperty(Intl.NumberFormat.prototype, 'resolvedOptions', function() {
194 if (%_IsConstructCall()) {
195 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
196 }
197
198 if (!this || typeof this !== 'object' ||
199 this.__initializedIntlObject !== 'numberformat') {
200 throw new TypeError('resolvedOptions method called on a non-object' +
201 ' or on a object that is not Intl.NumberFormat.');
202 }
203
204 var format = this;
205 var locale = getOptimalLanguageTag(format.resolved.requestedLocale,
206 format.resolved.locale);
207
208 var result = {
209 locale: locale,
210 numberingSystem: format.resolved.numberingSystem,
211 style: format.resolved.style,
212 useGrouping: format.resolved.useGrouping,
213 minimumIntegerDigits: format.resolved.minimumIntegerDigits,
214 minimumFractionDigits: format.resolved.minimumFractionDigits,
215 maximumFractionDigits: format.resolved.maximumFractionDigits,
216 };
217
218 if (result.style === 'currency') {
219 defineWECProperty(result, 'currency', format.resolved.currency);
220 defineWECProperty(result, 'currencyDisplay',
221 format.resolved.currencyDisplay);
222 }
223
224 if (format.resolved.hasOwnProperty('minimumSignificantDigits')) {
225 defineWECProperty(result, 'minimumSignificantDigits',
226 format.resolved.minimumSignificantDigits);
227 }
228
229 if (format.resolved.hasOwnProperty('maximumSignificantDigits')) {
230 defineWECProperty(result, 'maximumSignificantDigits',
231 format.resolved.maximumSignificantDigits);
232 }
233
234 return result;
235 },
236 ATTRIBUTES.DONT_ENUM
237 );
238 %FunctionSetName(Intl.NumberFormat.prototype.resolvedOptions,
239 'resolvedOptions');
240 %FunctionRemovePrototype(Intl.NumberFormat.prototype.resolvedOptions);
241 %SetNativeFlag(Intl.NumberFormat.prototype.resolvedOptions);
242
243
244 /**
245 * Returns the subset of the given locale list for which this locale list
246 * has a matching (possibly fallback) locale. Locales appear in the same
247 * order in the returned list as in the input list.
248 * Options are optional parameter.
249 */
250 %SetProperty(Intl.NumberFormat, 'supportedLocalesOf', function(locales) {
251 if (%_IsConstructCall()) {
252 throw new TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR);
253 }
254
255 return supportedLocalesOf('numberformat', locales, arguments[1]);
256 },
257 ATTRIBUTES.DONT_ENUM
258 );
259 %FunctionSetName(Intl.NumberFormat.supportedLocalesOf, 'supportedLocalesOf');
260 %FunctionRemovePrototype(Intl.NumberFormat.supportedLocalesOf);
261 %SetNativeFlag(Intl.NumberFormat.supportedLocalesOf);
262
263
264 /**
265 * Returns a String value representing the result of calling ToNumber(value)
266 * according to the effective locale and the formatting options of this
267 * NumberFormat.
268 */
269 function formatNumber(formatter, value) {
270 // Spec treats -0 and +0 as 0.
271 var number = Number(value);
272 if (number === -0) {
273 number = 0;
274 }
275
276 return %InternalNumberFormat(formatter.formatter, number);
277 }
278
279
280 /**
281 * Returns a Number that represents string value that was passed in.
282 */
283 function parseNumber(formatter, value) {
284 return %InternalNumberParse(formatter.formatter, String(value));
285 }
286
287
288 addBoundMethod(Intl.NumberFormat, 'format', formatNumber, 1);
289 addBoundMethod(Intl.NumberFormat, 'v8Parse', parseNumber, 1);
OLDNEW
« no previous file with comments | « src/extensions/i18n/locale.js ('k') | src/extensions/i18n/overrides.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698