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

Side by Side Diff: src/i18n.js

Issue 1143993003: Use shared container to manage imports/exports. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixed test for no-snap Created 5 years, 7 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
« no previous file with comments | « src/harmony-typedarray.js ('k') | src/iterator-prototype.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // ECMAScript 402 API implementation. 5 // ECMAScript 402 API implementation.
6 6
7 /** 7 /**
8 * Intl object is a single object that has some named properties, 8 * Intl object is a single object that has some named properties,
9 * all of which are constructors. 9 * all of which are constructors.
10 */ 10 */
11 (function(global, shared, exports) { 11 (function(global, utils) {
12 12
13 "use strict"; 13 "use strict";
14 14
15 %CheckIsBootstrapping(); 15 %CheckIsBootstrapping();
16 16
17 // -------------------------------------------------------------------
18 // Imports
19
17 var GlobalBoolean = global.Boolean; 20 var GlobalBoolean = global.Boolean;
18 var GlobalDate = global.Date; 21 var GlobalDate = global.Date;
19 var GlobalNumber = global.Number; 22 var GlobalNumber = global.Number;
20 var GlobalRegExp = global.RegExp; 23 var GlobalRegExp = global.RegExp;
21 var GlobalString = global.String; 24 var GlobalString = global.String;
22 25
23 var undefined = global.undefined; 26 var MathFloor;
27
28 utils.Import(function(from) {
29 MathFloor = from.MathFloor;
30 });
31
32 // -------------------------------------------------------------------
24 33
25 var Intl = {}; 34 var Intl = {};
26 35
27 %AddNamedProperty(global, "Intl", Intl, DONT_ENUM); 36 %AddNamedProperty(global, "Intl", Intl, DONT_ENUM);
28 37
29 /** 38 /**
30 * Caches available locales for each service. 39 * Caches available locales for each service.
31 */ 40 */
32 var AVAILABLE_LOCALES = { 41 var AVAILABLE_LOCALES = {
33 'collator': undefined, 42 'collator': UNDEFINED,
34 'numberformat': undefined, 43 'numberformat': UNDEFINED,
35 'dateformat': undefined, 44 'dateformat': UNDEFINED,
36 'breakiterator': undefined 45 'breakiterator': UNDEFINED
37 }; 46 };
38 47
39 /** 48 /**
40 * Caches default ICU locale. 49 * Caches default ICU locale.
41 */ 50 */
42 var DEFAULT_ICU_LOCALE = undefined; 51 var DEFAULT_ICU_LOCALE = UNDEFINED;
43 52
44 /** 53 /**
45 * Unicode extension regular expression. 54 * Unicode extension regular expression.
46 */ 55 */
47 var UNICODE_EXTENSION_RE = undefined; 56 var UNICODE_EXTENSION_RE = UNDEFINED;
48 57
49 function GetUnicodeExtensionRE() { 58 function GetUnicodeExtensionRE() {
50 if (UNICODE_EXTENSION_RE === undefined) { 59 if (IS_UNDEFINED(UNDEFINED)) {
51 UNICODE_EXTENSION_RE = new GlobalRegExp('-u(-[a-z0-9]{2,8})+', 'g'); 60 UNICODE_EXTENSION_RE = new GlobalRegExp('-u(-[a-z0-9]{2,8})+', 'g');
52 } 61 }
53 return UNICODE_EXTENSION_RE; 62 return UNICODE_EXTENSION_RE;
54 } 63 }
55 64
56 /** 65 /**
57 * Matches any Unicode extension. 66 * Matches any Unicode extension.
58 */ 67 */
59 var ANY_EXTENSION_RE = undefined; 68 var ANY_EXTENSION_RE = UNDEFINED;
60 69
61 function GetAnyExtensionRE() { 70 function GetAnyExtensionRE() {
62 if (ANY_EXTENSION_RE === undefined) { 71 if (IS_UNDEFINED(ANY_EXTENSION_RE)) {
63 ANY_EXTENSION_RE = new GlobalRegExp('-[a-z0-9]{1}-.*', 'g'); 72 ANY_EXTENSION_RE = new GlobalRegExp('-[a-z0-9]{1}-.*', 'g');
64 } 73 }
65 return ANY_EXTENSION_RE; 74 return ANY_EXTENSION_RE;
66 } 75 }
67 76
68 /** 77 /**
69 * Replace quoted text (single quote, anything but the quote and quote again). 78 * Replace quoted text (single quote, anything but the quote and quote again).
70 */ 79 */
71 var QUOTED_STRING_RE = undefined; 80 var QUOTED_STRING_RE = UNDEFINED;
72 81
73 function GetQuotedStringRE() { 82 function GetQuotedStringRE() {
74 if (QUOTED_STRING_RE === undefined) { 83 if (IS_UNDEFINED(QUOTED_STRING_RE)) {
75 QUOTED_STRING_RE = new GlobalRegExp("'[^']+'", 'g'); 84 QUOTED_STRING_RE = new GlobalRegExp("'[^']+'", 'g');
76 } 85 }
77 return QUOTED_STRING_RE; 86 return QUOTED_STRING_RE;
78 } 87 }
79 88
80 /** 89 /**
81 * Matches valid service name. 90 * Matches valid service name.
82 */ 91 */
83 var SERVICE_RE = undefined; 92 var SERVICE_RE = UNDEFINED;
84 93
85 function GetServiceRE() { 94 function GetServiceRE() {
86 if (SERVICE_RE === undefined) { 95 if (IS_UNDEFINED(SERVICE_RE)) {
87 SERVICE_RE = 96 SERVICE_RE =
88 new GlobalRegExp('^(collator|numberformat|dateformat|breakiterator)$'); 97 new GlobalRegExp('^(collator|numberformat|dateformat|breakiterator)$');
89 } 98 }
90 return SERVICE_RE; 99 return SERVICE_RE;
91 } 100 }
92 101
93 /** 102 /**
94 * Validates a language tag against bcp47 spec. 103 * Validates a language tag against bcp47 spec.
95 * Actual value is assigned on first run. 104 * Actual value is assigned on first run.
96 */ 105 */
97 var LANGUAGE_TAG_RE = undefined; 106 var LANGUAGE_TAG_RE = UNDEFINED;
98 107
99 function GetLanguageTagRE() { 108 function GetLanguageTagRE() {
100 if (LANGUAGE_TAG_RE === undefined) { 109 if (IS_UNDEFINED(LANGUAGE_TAG_RE)) {
101 BuildLanguageTagREs(); 110 BuildLanguageTagREs();
102 } 111 }
103 return LANGUAGE_TAG_RE; 112 return LANGUAGE_TAG_RE;
104 } 113 }
105 114
106 /** 115 /**
107 * Helps find duplicate variants in the language tag. 116 * Helps find duplicate variants in the language tag.
108 */ 117 */
109 var LANGUAGE_VARIANT_RE = undefined; 118 var LANGUAGE_VARIANT_RE = UNDEFINED;
110 119
111 function GetLanguageVariantRE() { 120 function GetLanguageVariantRE() {
112 if (LANGUAGE_VARIANT_RE === undefined) { 121 if (IS_UNDEFINED(LANGUAGE_VARIANT_RE)) {
113 BuildLanguageTagREs(); 122 BuildLanguageTagREs();
114 } 123 }
115 return LANGUAGE_VARIANT_RE; 124 return LANGUAGE_VARIANT_RE;
116 } 125 }
117 126
118 /** 127 /**
119 * Helps find duplicate singletons in the language tag. 128 * Helps find duplicate singletons in the language tag.
120 */ 129 */
121 var LANGUAGE_SINGLETON_RE = undefined; 130 var LANGUAGE_SINGLETON_RE = UNDEFINED;
122 131
123 function GetLanguageSingletonRE() { 132 function GetLanguageSingletonRE() {
124 if (LANGUAGE_SINGLETON_RE === undefined) { 133 if (IS_UNDEFINED(LANGUAGE_SINGLETON_RE)) {
125 BuildLanguageTagREs(); 134 BuildLanguageTagREs();
126 } 135 }
127 return LANGUAGE_SINGLETON_RE; 136 return LANGUAGE_SINGLETON_RE;
128 } 137 }
129 138
130 /** 139 /**
131 * Matches valid IANA time zone names. 140 * Matches valid IANA time zone names.
132 */ 141 */
133 var TIMEZONE_NAME_CHECK_RE = undefined; 142 var TIMEZONE_NAME_CHECK_RE = UNDEFINED;
134 143
135 function GetTimezoneNameCheckRE() { 144 function GetTimezoneNameCheckRE() {
136 if (TIMEZONE_NAME_CHECK_RE === undefined) { 145 if (IS_UNDEFINED(TIMEZONE_NAME_CHECK_RE)) {
137 TIMEZONE_NAME_CHECK_RE = 146 TIMEZONE_NAME_CHECK_RE =
138 new GlobalRegExp('^([A-Za-z]+)/([A-Za-z]+)(?:_([A-Za-z]+))*$'); 147 new GlobalRegExp('^([A-Za-z]+)/([A-Za-z]+)(?:_([A-Za-z]+))*$');
139 } 148 }
140 return TIMEZONE_NAME_CHECK_RE; 149 return TIMEZONE_NAME_CHECK_RE;
141 } 150 }
142 151
143 /** 152 /**
144 * Adds bound method to the prototype of the given object. 153 * Adds bound method to the prototype of the given object.
145 */ 154 */
146 function addBoundMethod(obj, methodName, implementation, length) { 155 function addBoundMethod(obj, methodName, implementation, length) {
147 function getter() { 156 function getter() {
148 if (!%IsInitializedIntlObject(this)) { 157 if (!%IsInitializedIntlObject(this)) {
149 throw MakeTypeError(kMethodCalledOnWrongObject, methodName); 158 throw MakeTypeError(kMethodCalledOnWrongObject, methodName);
150 } 159 }
151 var internalName = '__bound' + methodName + '__'; 160 var internalName = '__bound' + methodName + '__';
152 if (this[internalName] === undefined) { 161 if (IS_UNDEFINED(this[internalName])) {
153 var that = this; 162 var that = this;
154 var boundMethod; 163 var boundMethod;
155 if (length === undefined || length === 2) { 164 if (IS_UNDEFINED(length) || length === 2) {
156 boundMethod = function(x, y) { 165 boundMethod = function(x, y) {
157 if (%_IsConstructCall()) { 166 if (%_IsConstructCall()) {
158 throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); 167 throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
159 } 168 }
160 return implementation(that, x, y); 169 return implementation(that, x, y);
161 } 170 }
162 } else if (length === 1) { 171 } else if (length === 1) {
163 boundMethod = function(x) { 172 boundMethod = function(x) {
164 if (%_IsConstructCall()) { 173 if (%_IsConstructCall()) {
165 throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); 174 throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 /** 213 /**
205 * Returns an intersection of locales and service supported locales. 214 * Returns an intersection of locales and service supported locales.
206 * Parameter locales is treated as a priority list. 215 * Parameter locales is treated as a priority list.
207 */ 216 */
208 function supportedLocalesOf(service, locales, options) { 217 function supportedLocalesOf(service, locales, options) {
209 if (IS_NULL(service.match(GetServiceRE()))) { 218 if (IS_NULL(service.match(GetServiceRE()))) {
210 throw MakeError(kWrongServiceType, service); 219 throw MakeError(kWrongServiceType, service);
211 } 220 }
212 221
213 // Provide defaults if matcher was not specified. 222 // Provide defaults if matcher was not specified.
214 if (options === undefined) { 223 if (IS_UNDEFINED(options)) {
215 options = {}; 224 options = {};
216 } else { 225 } else {
217 options = $toObject(options); 226 options = $toObject(options);
218 } 227 }
219 228
220 var matcher = options.localeMatcher; 229 var matcher = options.localeMatcher;
221 if (matcher !== undefined) { 230 if (!IS_UNDEFINED(matcher)) {
222 matcher = GlobalString(matcher); 231 matcher = GlobalString(matcher);
223 if (matcher !== 'lookup' && matcher !== 'best fit') { 232 if (matcher !== 'lookup' && matcher !== 'best fit') {
224 throw MakeRangeError(kLocaleMatcher, matcher); 233 throw MakeRangeError(kLocaleMatcher, matcher);
225 } 234 }
226 } else { 235 } else {
227 matcher = 'best fit'; 236 matcher = 'best fit';
228 } 237 }
229 238
230 var requestedLocales = initializeLocaleList(locales); 239 var requestedLocales = initializeLocaleList(locales);
231 240
232 // Cache these, they don't ever change per service. 241 // Cache these, they don't ever change per service.
233 if (AVAILABLE_LOCALES[service] === undefined) { 242 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
234 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); 243 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
235 } 244 }
236 245
237 // Use either best fit or lookup algorithm to match locales. 246 // Use either best fit or lookup algorithm to match locales.
238 if (matcher === 'best fit') { 247 if (matcher === 'best fit') {
239 return initializeLocaleList(bestFitSupportedLocalesOf( 248 return initializeLocaleList(bestFitSupportedLocalesOf(
240 requestedLocales, AVAILABLE_LOCALES[service])); 249 requestedLocales, AVAILABLE_LOCALES[service]));
241 } 250 }
242 251
243 return initializeLocaleList(lookupSupportedLocalesOf( 252 return initializeLocaleList(lookupSupportedLocalesOf(
244 requestedLocales, AVAILABLE_LOCALES[service])); 253 requestedLocales, AVAILABLE_LOCALES[service]));
245 } 254 }
246 255
247 256
248 /** 257 /**
249 * Returns the subset of the provided BCP 47 language priority list for which 258 * Returns the subset of the provided BCP 47 language priority list for which
250 * this service has a matching locale when using the BCP 47 Lookup algorithm. 259 * this service has a matching locale when using the BCP 47 Lookup algorithm.
251 * Locales appear in the same order in the returned list as in the input list. 260 * Locales appear in the same order in the returned list as in the input list.
252 */ 261 */
253 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { 262 function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
254 var matchedLocales = []; 263 var matchedLocales = [];
255 for (var i = 0; i < requestedLocales.length; ++i) { 264 for (var i = 0; i < requestedLocales.length; ++i) {
256 // Remove -u- extension. 265 // Remove -u- extension.
257 var locale = requestedLocales[i].replace(GetUnicodeExtensionRE(), ''); 266 var locale = requestedLocales[i].replace(GetUnicodeExtensionRE(), '');
258 do { 267 do {
259 if (availableLocales[locale] !== undefined) { 268 if (!IS_UNDEFINED(availableLocales[locale])) {
260 // Push requested locale not the resolved one. 269 // Push requested locale not the resolved one.
261 matchedLocales.push(requestedLocales[i]); 270 matchedLocales.push(requestedLocales[i]);
262 break; 271 break;
263 } 272 }
264 // Truncate locale if possible, if not break. 273 // Truncate locale if possible, if not break.
265 var pos = locale.lastIndexOf('-'); 274 var pos = locale.lastIndexOf('-');
266 if (pos === -1) { 275 if (pos === -1) {
267 break; 276 break;
268 } 277 }
269 locale = locale.substring(0, pos); 278 locale = locale.substring(0, pos);
(...skipping 15 matching lines...) Expand all
285 return lookupSupportedLocalesOf(requestedLocales, availableLocales); 294 return lookupSupportedLocalesOf(requestedLocales, availableLocales);
286 } 295 }
287 296
288 297
289 /** 298 /**
290 * Returns a getOption function that extracts property value for given 299 * Returns a getOption function that extracts property value for given
291 * options object. If property is missing it returns defaultValue. If value 300 * options object. If property is missing it returns defaultValue. If value
292 * is out of range for that property it throws RangeError. 301 * is out of range for that property it throws RangeError.
293 */ 302 */
294 function getGetOption(options, caller) { 303 function getGetOption(options, caller) {
295 if (options === undefined) throw MakeError(kDefaultOptionsMissing, caller); 304 if (IS_UNDEFINED(options)) throw MakeError(kDefaultOptionsMissing, caller);
296 305
297 var getOption = function getOption(property, type, values, defaultValue) { 306 var getOption = function getOption(property, type, values, defaultValue) {
298 if (options[property] !== undefined) { 307 if (!IS_UNDEFINED(options[property])) {
299 var value = options[property]; 308 var value = options[property];
300 switch (type) { 309 switch (type) {
301 case 'boolean': 310 case 'boolean':
302 value = GlobalBoolean(value); 311 value = GlobalBoolean(value);
303 break; 312 break;
304 case 'string': 313 case 'string':
305 value = GlobalString(value); 314 value = GlobalString(value);
306 break; 315 break;
307 case 'number': 316 case 'number':
308 value = GlobalNumber(value); 317 value = GlobalNumber(value);
309 break; 318 break;
310 default: 319 default:
311 throw MakeError(kWrongValueType); 320 throw MakeError(kWrongValueType);
312 } 321 }
313 if (values !== undefined && values.indexOf(value) === -1) { 322 if (!IS_UNDEFINED(values) && values.indexOf(value) === -1) {
314 throw MakeRangeError(kValueOutOfRange, value, caller, property); 323 throw MakeRangeError(kValueOutOfRange, value, caller, property);
315 } 324 }
316 325
317 return value; 326 return value;
318 } 327 }
319 328
320 return defaultValue; 329 return defaultValue;
321 } 330 }
322 331
323 return getOption; 332 return getOption;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 /** 366 /**
358 * Returns best matched supported locale and extension info using basic 367 * Returns best matched supported locale and extension info using basic
359 * lookup algorithm. 368 * lookup algorithm.
360 */ 369 */
361 function lookupMatcher(service, requestedLocales) { 370 function lookupMatcher(service, requestedLocales) {
362 if (IS_NULL(service.match(GetServiceRE()))) { 371 if (IS_NULL(service.match(GetServiceRE()))) {
363 throw MakeError(kWrongServiceType, service); 372 throw MakeError(kWrongServiceType, service);
364 } 373 }
365 374
366 // Cache these, they don't ever change per service. 375 // Cache these, they don't ever change per service.
367 if (AVAILABLE_LOCALES[service] === undefined) { 376 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
368 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); 377 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
369 } 378 }
370 379
371 for (var i = 0; i < requestedLocales.length; ++i) { 380 for (var i = 0; i < requestedLocales.length; ++i) {
372 // Remove all extensions. 381 // Remove all extensions.
373 var locale = requestedLocales[i].replace(GetAnyExtensionRE(), ''); 382 var locale = requestedLocales[i].replace(GetAnyExtensionRE(), '');
374 do { 383 do {
375 if (AVAILABLE_LOCALES[service][locale] !== undefined) { 384 if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) {
376 // Return the resolved locale and extension. 385 // Return the resolved locale and extension.
377 var extensionMatch = requestedLocales[i].match(GetUnicodeExtensionRE()); 386 var extensionMatch = requestedLocales[i].match(GetUnicodeExtensionRE());
378 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; 387 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
379 return {'locale': locale, 'extension': extension, 'position': i}; 388 return {'locale': locale, 'extension': extension, 'position': i};
380 } 389 }
381 // Truncate locale if possible. 390 // Truncate locale if possible.
382 var pos = locale.lastIndexOf('-'); 391 var pos = locale.lastIndexOf('-');
383 if (pos === -1) { 392 if (pos === -1) {
384 break; 393 break;
385 } 394 }
386 locale = locale.substring(0, pos); 395 locale = locale.substring(0, pos);
387 } while (true); 396 } while (true);
388 } 397 }
389 398
390 // Didn't find a match, return default. 399 // Didn't find a match, return default.
391 if (DEFAULT_ICU_LOCALE === undefined) { 400 if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
392 DEFAULT_ICU_LOCALE = %GetDefaultICULocale(); 401 DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
393 } 402 }
394 403
395 return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1}; 404 return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
396 } 405 }
397 406
398 407
399 /** 408 /**
400 * Returns best matched supported locale and extension info using 409 * Returns best matched supported locale and extension info using
401 * implementation dependend algorithm. 410 * implementation dependend algorithm.
(...skipping 14 matching lines...) Expand all
416 425
417 // Assume ['', 'u', ...] input, but don't throw. 426 // Assume ['', 'u', ...] input, but don't throw.
418 if (extensionSplit.length <= 2 || 427 if (extensionSplit.length <= 2 ||
419 (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) { 428 (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) {
420 return {}; 429 return {};
421 } 430 }
422 431
423 // Key is {2}alphanum, value is {3,8}alphanum. 432 // Key is {2}alphanum, value is {3,8}alphanum.
424 // Some keys may not have explicit values (booleans). 433 // Some keys may not have explicit values (booleans).
425 var extensionMap = {}; 434 var extensionMap = {};
426 var previousKey = undefined; 435 var previousKey = UNDEFINED;
427 for (var i = 2; i < extensionSplit.length; ++i) { 436 for (var i = 2; i < extensionSplit.length; ++i) {
428 var length = extensionSplit[i].length; 437 var length = extensionSplit[i].length;
429 var element = extensionSplit[i]; 438 var element = extensionSplit[i];
430 if (length === 2) { 439 if (length === 2) {
431 extensionMap[element] = undefined; 440 extensionMap[element] = UNDEFINED;
432 previousKey = element; 441 previousKey = element;
433 } else if (length >= 3 && length <=8 && previousKey !== undefined) { 442 } else if (length >= 3 && length <=8 && !IS_UNDEFINED(previousKey)) {
434 extensionMap[previousKey] = element; 443 extensionMap[previousKey] = element;
435 previousKey = undefined; 444 previousKey = UNDEFINED;
436 } else { 445 } else {
437 // There is a value that's too long, or that doesn't have a key. 446 // There is a value that's too long, or that doesn't have a key.
438 return {}; 447 return {};
439 } 448 }
440 } 449 }
441 450
442 return extensionMap; 451 return extensionMap;
443 } 452 }
444 453
445 454
(...skipping 12 matching lines...) Expand all
458 467
459 var updateExtension = function updateExtension(key, value) { 468 var updateExtension = function updateExtension(key, value) {
460 return '-' + key + '-' + GlobalString(value); 469 return '-' + key + '-' + GlobalString(value);
461 } 470 }
462 471
463 var updateProperty = function updateProperty(property, type, value) { 472 var updateProperty = function updateProperty(property, type, value) {
464 if (type === 'boolean' && (typeof value === 'string')) { 473 if (type === 'boolean' && (typeof value === 'string')) {
465 value = (value === 'true') ? true : false; 474 value = (value === 'true') ? true : false;
466 } 475 }
467 476
468 if (property !== undefined) { 477 if (!IS_UNDEFINED(property)) {
469 defineWEProperty(outOptions, property, value); 478 defineWEProperty(outOptions, property, value);
470 } 479 }
471 } 480 }
472 481
473 for (var key in keyValues) { 482 for (var key in keyValues) {
474 if (keyValues.hasOwnProperty(key)) { 483 if (keyValues.hasOwnProperty(key)) {
475 var value = undefined; 484 var value = UNDEFINED;
476 var map = keyValues[key]; 485 var map = keyValues[key];
477 if (map.property !== undefined) { 486 if (!IS_UNDEFINED(map.property)) {
478 // This may return true if user specifies numeric: 'false', since 487 // This may return true if user specifies numeric: 'false', since
479 // Boolean('nonempty') === true. 488 // Boolean('nonempty') === true.
480 value = getOption(map.property, map.type, map.values); 489 value = getOption(map.property, map.type, map.values);
481 } 490 }
482 if (value !== undefined) { 491 if (!IS_UNDEFINED(value)) {
483 updateProperty(map.property, map.type, value); 492 updateProperty(map.property, map.type, value);
484 extension += updateExtension(key, value); 493 extension += updateExtension(key, value);
485 continue; 494 continue;
486 } 495 }
487 // User options didn't have it, check Unicode extension. 496 // User options didn't have it, check Unicode extension.
488 // Here we want to convert strings 'true', 'false' into proper Boolean 497 // Here we want to convert strings 'true', 'false' into proper Boolean
489 // values (not a user error). 498 // values (not a user error).
490 if (extensionMap.hasOwnProperty(key)) { 499 if (extensionMap.hasOwnProperty(key)) {
491 value = extensionMap[key]; 500 value = extensionMap[key];
492 if (value !== undefined) { 501 if (!IS_UNDEFINED(value)) {
493 updateProperty(map.property, map.type, value); 502 updateProperty(map.property, map.type, value);
494 extension += updateExtension(key, value); 503 extension += updateExtension(key, value);
495 } else if (map.type === 'boolean') { 504 } else if (map.type === 'boolean') {
496 // Boolean keys are allowed not to have values in Unicode extension. 505 // Boolean keys are allowed not to have values in Unicode extension.
497 // Those default to true. 506 // Those default to true.
498 updateProperty(map.property, map.type, true); 507 updateProperty(map.property, map.type, true);
499 extension += updateExtension(key, true); 508 extension += updateExtension(key, true);
500 } 509 }
501 } 510 }
502 } 511 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 $objectDefineProperty(object, property, 592 $objectDefineProperty(object, property,
584 {value: value, writable: true, enumerable: true}); 593 {value: value, writable: true, enumerable: true});
585 } 594 }
586 595
587 596
588 /** 597 /**
589 * Adds property to an object if the value is not undefined. 598 * Adds property to an object if the value is not undefined.
590 * Sets configurable descriptor to false. 599 * Sets configurable descriptor to false.
591 */ 600 */
592 function addWEPropertyIfDefined(object, property, value) { 601 function addWEPropertyIfDefined(object, property, value) {
593 if (value !== undefined) { 602 if (!IS_UNDEFINED(value)) {
594 defineWEProperty(object, property, value); 603 defineWEProperty(object, property, value);
595 } 604 }
596 } 605 }
597 606
598 607
599 /** 608 /**
600 * Defines a property and sets writable, enumerable and configurable to true. 609 * Defines a property and sets writable, enumerable and configurable to true.
601 */ 610 */
602 function defineWECProperty(object, property, value) { 611 function defineWECProperty(object, property, value) {
603 $objectDefineProperty(object, property, {value: value, 612 $objectDefineProperty(object, property, {value: value,
604 writable: true, 613 writable: true,
605 enumerable: true, 614 enumerable: true,
606 configurable: true}); 615 configurable: true});
607 } 616 }
608 617
609 618
610 /** 619 /**
611 * Adds property to an object if the value is not undefined. 620 * Adds property to an object if the value is not undefined.
612 * Sets all descriptors to true. 621 * Sets all descriptors to true.
613 */ 622 */
614 function addWECPropertyIfDefined(object, property, value) { 623 function addWECPropertyIfDefined(object, property, value) {
615 if (value !== undefined) { 624 if (!IS_UNDEFINED(value)) {
616 defineWECProperty(object, property, value); 625 defineWECProperty(object, property, value);
617 } 626 }
618 } 627 }
619 628
620 629
621 /** 630 /**
622 * Returns titlecased word, aMeRricA -> America. 631 * Returns titlecased word, aMeRricA -> America.
623 */ 632 */
624 function toTitleCaseWord(word) { 633 function toTitleCaseWord(word) {
625 return word.substr(0, 1).toUpperCase() + word.substr(1).toLowerCase(); 634 return word.substr(0, 1).toUpperCase() + word.substr(1).toLowerCase();
(...skipping 27 matching lines...) Expand all
653 return tag; 662 return tag;
654 } 663 }
655 664
656 665
657 /** 666 /**
658 * Returns an array where all locales are canonicalized and duplicates removed. 667 * Returns an array where all locales are canonicalized and duplicates removed.
659 * Throws on locales that are not well formed BCP47 tags. 668 * Throws on locales that are not well formed BCP47 tags.
660 */ 669 */
661 function initializeLocaleList(locales) { 670 function initializeLocaleList(locales) {
662 var seen = []; 671 var seen = [];
663 if (locales === undefined) { 672 if (IS_UNDEFINED(locales)) {
664 // Constructor is called without arguments. 673 // Constructor is called without arguments.
665 seen = []; 674 seen = [];
666 } else { 675 } else {
667 // We allow single string localeID. 676 // We allow single string localeID.
668 if (typeof locales === 'string') { 677 if (typeof locales === 'string') {
669 seen.push(canonicalizeLanguageTag(locales)); 678 seen.push(canonicalizeLanguageTag(locales));
670 return freezeArray(seen); 679 return freezeArray(seen);
671 } 680 }
672 681
673 var o = $toObject(locales); 682 var o = $toObject(locales);
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 795
787 /** 796 /**
788 * Initializes the given object so it's a valid Collator instance. 797 * Initializes the given object so it's a valid Collator instance.
789 * Useful for subclassing. 798 * Useful for subclassing.
790 */ 799 */
791 function initializeCollator(collator, locales, options) { 800 function initializeCollator(collator, locales, options) {
792 if (%IsInitializedIntlObject(collator)) { 801 if (%IsInitializedIntlObject(collator)) {
793 throw MakeTypeError(kReinitializeIntl, "Collator"); 802 throw MakeTypeError(kReinitializeIntl, "Collator");
794 } 803 }
795 804
796 if (options === undefined) { 805 if (IS_UNDEFINED(options)) {
797 options = {}; 806 options = {};
798 } 807 }
799 808
800 var getOption = getGetOption(options, 'collator'); 809 var getOption = getGetOption(options, 'collator');
801 810
802 var internalOptions = {}; 811 var internalOptions = {};
803 812
804 defineWEProperty(internalOptions, 'usage', getOption( 813 defineWEProperty(internalOptions, 'usage', getOption(
805 'usage', 'string', ['sort', 'search'], 'sort')); 814 'usage', 'string', ['sort', 'search'], 'sort'));
806 815
807 var sensitivity = getOption('sensitivity', 'string', 816 var sensitivity = getOption('sensitivity', 'string',
808 ['base', 'accent', 'case', 'variant']); 817 ['base', 'accent', 'case', 'variant']);
809 if (sensitivity === undefined && internalOptions.usage === 'sort') { 818 if (IS_UNDEFINED(sensitivity) && internalOptions.usage === 'sort') {
810 sensitivity = 'variant'; 819 sensitivity = 'variant';
811 } 820 }
812 defineWEProperty(internalOptions, 'sensitivity', sensitivity); 821 defineWEProperty(internalOptions, 'sensitivity', sensitivity);
813 822
814 defineWEProperty(internalOptions, 'ignorePunctuation', getOption( 823 defineWEProperty(internalOptions, 'ignorePunctuation', getOption(
815 'ignorePunctuation', 'boolean', undefined, false)); 824 'ignorePunctuation', 'boolean', UNDEFINED, false));
816 825
817 var locale = resolveLocale('collator', locales, options); 826 var locale = resolveLocale('collator', locales, options);
818 827
819 // ICU can't take kb, kc... parameters through localeID, so we need to pass 828 // ICU can't take kb, kc... parameters through localeID, so we need to pass
820 // them as options. 829 // them as options.
821 // One exception is -co- which has to be part of the extension, but only for 830 // One exception is -co- which has to be part of the extension, but only for
822 // usage: sort, and its value can't be 'standard' or 'search'. 831 // usage: sort, and its value can't be 'standard' or 'search'.
823 var extensionMap = parseExtension(locale.extension); 832 var extensionMap = parseExtension(locale.extension);
824 833
825 /** 834 /**
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 currency.match(/[^A-Za-z]/) == null; 1000 currency.match(/[^A-Za-z]/) == null;
992 } 1001 }
993 1002
994 1003
995 /** 1004 /**
996 * Returns the valid digit count for a property, or throws RangeError on 1005 * Returns the valid digit count for a property, or throws RangeError on
997 * a value out of the range. 1006 * a value out of the range.
998 */ 1007 */
999 function getNumberOption(options, property, min, max, fallback) { 1008 function getNumberOption(options, property, min, max, fallback) {
1000 var value = options[property]; 1009 var value = options[property];
1001 if (value !== undefined) { 1010 if (!IS_UNDEFINED(value)) {
1002 value = GlobalNumber(value); 1011 value = GlobalNumber(value);
1003 if ($isNaN(value) || value < min || value > max) { 1012 if ($isNaN(value) || value < min || value > max) {
1004 throw MakeRangeError(kPropertyValueOutOfRange, property); 1013 throw MakeRangeError(kPropertyValueOutOfRange, property);
1005 } 1014 }
1006 return $floor(value); 1015 return MathFloor(value);
1007 } 1016 }
1008 1017
1009 return fallback; 1018 return fallback;
1010 } 1019 }
1011 1020
1012 1021
1013 /** 1022 /**
1014 * Initializes the given object so it's a valid NumberFormat instance. 1023 * Initializes the given object so it's a valid NumberFormat instance.
1015 * Useful for subclassing. 1024 * Useful for subclassing.
1016 */ 1025 */
1017 function initializeNumberFormat(numberFormat, locales, options) { 1026 function initializeNumberFormat(numberFormat, locales, options) {
1018 if (%IsInitializedIntlObject(numberFormat)) { 1027 if (%IsInitializedIntlObject(numberFormat)) {
1019 throw MakeTypeError(kReinitializeIntl, "NumberFormat"); 1028 throw MakeTypeError(kReinitializeIntl, "NumberFormat");
1020 } 1029 }
1021 1030
1022 if (options === undefined) { 1031 if (IS_UNDEFINED(options)) {
1023 options = {}; 1032 options = {};
1024 } 1033 }
1025 1034
1026 var getOption = getGetOption(options, 'numberformat'); 1035 var getOption = getGetOption(options, 'numberformat');
1027 1036
1028 var locale = resolveLocale('numberformat', locales, options); 1037 var locale = resolveLocale('numberformat', locales, options);
1029 1038
1030 var internalOptions = {}; 1039 var internalOptions = {};
1031 defineWEProperty(internalOptions, 'style', getOption( 1040 defineWEProperty(internalOptions, 'style', getOption(
1032 'style', 'string', ['decimal', 'percent', 'currency'], 'decimal')); 1041 'style', 'string', ['decimal', 'percent', 'currency'], 'decimal'));
1033 1042
1034 var currency = getOption('currency', 'string'); 1043 var currency = getOption('currency', 'string');
1035 if (currency !== undefined && !isWellFormedCurrencyCode(currency)) { 1044 if (!IS_UNDEFINED(currency) && !isWellFormedCurrencyCode(currency)) {
1036 throw MakeRangeError(kInvalidCurrencyCode, currency); 1045 throw MakeRangeError(kInvalidCurrencyCode, currency);
1037 } 1046 }
1038 1047
1039 if (internalOptions.style === 'currency' && currency === undefined) { 1048 if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) {
1040 throw MakeTypeError(kCurrencyCode); 1049 throw MakeTypeError(kCurrencyCode);
1041 } 1050 }
1042 1051
1043 var currencyDisplay = getOption( 1052 var currencyDisplay = getOption(
1044 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol'); 1053 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
1045 if (internalOptions.style === 'currency') { 1054 if (internalOptions.style === 'currency') {
1046 defineWEProperty(internalOptions, 'currency', currency.toUpperCase()); 1055 defineWEProperty(internalOptions, 'currency', currency.toUpperCase());
1047 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay); 1056 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay);
1048 } 1057 }
1049 1058
1050 // Digit ranges. 1059 // Digit ranges.
1051 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1); 1060 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
1052 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid); 1061 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
1053 1062
1054 var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0); 1063 var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
1055 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd); 1064 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
1056 1065
1057 var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, 3); 1066 var mxfd = getNumberOption(options, 'maximumFractionDigits', mnfd, 20, 3);
1058 defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd); 1067 defineWEProperty(internalOptions, 'maximumFractionDigits', mxfd);
1059 1068
1060 var mnsd = options['minimumSignificantDigits']; 1069 var mnsd = options['minimumSignificantDigits'];
1061 var mxsd = options['maximumSignificantDigits']; 1070 var mxsd = options['maximumSignificantDigits'];
1062 if (mnsd !== undefined || mxsd !== undefined) { 1071 if (!IS_UNDEFINED(mnsd) || !IS_UNDEFINED(mxsd)) {
1063 mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 0); 1072 mnsd = getNumberOption(options, 'minimumSignificantDigits', 1, 21, 0);
1064 defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd); 1073 defineWEProperty(internalOptions, 'minimumSignificantDigits', mnsd);
1065 1074
1066 mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21); 1075 mxsd = getNumberOption(options, 'maximumSignificantDigits', mnsd, 21, 21);
1067 defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd); 1076 defineWEProperty(internalOptions, 'maximumSignificantDigits', mxsd);
1068 } 1077 }
1069 1078
1070 // Grouping. 1079 // Grouping.
1071 defineWEProperty(internalOptions, 'useGrouping', getOption( 1080 defineWEProperty(internalOptions, 'useGrouping', getOption(
1072 'useGrouping', 'boolean', undefined, true)); 1081 'useGrouping', 'boolean', UNDEFINED, true));
1073 1082
1074 // ICU prefers options to be passed using -u- extension key/values for 1083 // ICU prefers options to be passed using -u- extension key/values for
1075 // number format, so we need to build that. 1084 // number format, so we need to build that.
1076 var extensionMap = parseExtension(locale.extension); 1085 var extensionMap = parseExtension(locale.extension);
1077 1086
1078 /** 1087 /**
1079 * Map of Unicode extensions to option properties, and their values and types, 1088 * Map of Unicode extensions to option properties, and their values and types,
1080 * for a number format. 1089 * for a number format.
1081 */ 1090 */
1082 var NUMBER_FORMAT_KEY_MAP = { 1091 var NUMBER_FORMAT_KEY_MAP = {
1083 'nu': {'property': undefined, 'type': 'string'} 1092 'nu': {'property': UNDEFINED, 'type': 'string'}
1084 }; 1093 };
1085 1094
1086 var extension = setOptions(options, extensionMap, NUMBER_FORMAT_KEY_MAP, 1095 var extension = setOptions(options, extensionMap, NUMBER_FORMAT_KEY_MAP,
1087 getOption, internalOptions); 1096 getOption, internalOptions);
1088 1097
1089 var requestedLocale = locale.locale + extension; 1098 var requestedLocale = locale.locale + extension;
1090 var resolved = $objectDefineProperties({}, { 1099 var resolved = $objectDefineProperties({}, {
1091 currency: {writable: true}, 1100 currency: {writable: true},
1092 currencyDisplay: {writable: true}, 1101 currencyDisplay: {writable: true},
1093 locale: {writable: true}, 1102 locale: {writable: true},
1094 maximumFractionDigits: {writable: true}, 1103 maximumFractionDigits: {writable: true},
1095 minimumFractionDigits: {writable: true}, 1104 minimumFractionDigits: {writable: true},
1096 minimumIntegerDigits: {writable: true}, 1105 minimumIntegerDigits: {writable: true},
1097 numberingSystem: {writable: true}, 1106 numberingSystem: {writable: true},
1098 requestedLocale: {value: requestedLocale, writable: true}, 1107 requestedLocale: {value: requestedLocale, writable: true},
1099 style: {value: internalOptions.style, writable: true}, 1108 style: {value: internalOptions.style, writable: true},
1100 useGrouping: {writable: true} 1109 useGrouping: {writable: true}
1101 }); 1110 });
1102 if (internalOptions.hasOwnProperty('minimumSignificantDigits')) { 1111 if (internalOptions.hasOwnProperty('minimumSignificantDigits')) {
1103 defineWEProperty(resolved, 'minimumSignificantDigits', undefined); 1112 defineWEProperty(resolved, 'minimumSignificantDigits', UNDEFINED);
1104 } 1113 }
1105 if (internalOptions.hasOwnProperty('maximumSignificantDigits')) { 1114 if (internalOptions.hasOwnProperty('maximumSignificantDigits')) {
1106 defineWEProperty(resolved, 'maximumSignificantDigits', undefined); 1115 defineWEProperty(resolved, 'maximumSignificantDigits', UNDEFINED);
1107 } 1116 }
1108 var formatter = %CreateNumberFormat(requestedLocale, 1117 var formatter = %CreateNumberFormat(requestedLocale,
1109 internalOptions, 1118 internalOptions,
1110 resolved); 1119 resolved);
1111 1120
1112 // We can't get information about number or currency style from ICU, so we 1121 // We can't get information about number or currency style from ICU, so we
1113 // assume user request was fulfilled. 1122 // assume user request was fulfilled.
1114 if (internalOptions.style === 'currency') { 1123 if (internalOptions.style === 'currency') {
1115 $objectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay, 1124 $objectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
1116 writable: true}); 1125 writable: true});
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 ['2-digit', 'numeric', 'narrow', 'short', 'long']); 1274 ['2-digit', 'numeric', 'narrow', 'short', 'long']);
1266 ldmlString += appendToLDMLString(option, {'2-digit': 'MM', 'numeric': 'M', 1275 ldmlString += appendToLDMLString(option, {'2-digit': 'MM', 'numeric': 'M',
1267 'narrow': 'MMMMM', 'short': 'MMM', 'long': 'MMMM'}); 1276 'narrow': 'MMMMM', 'short': 'MMM', 'long': 'MMMM'});
1268 1277
1269 option = getOption('day', 'string', ['2-digit', 'numeric']); 1278 option = getOption('day', 'string', ['2-digit', 'numeric']);
1270 ldmlString += appendToLDMLString( 1279 ldmlString += appendToLDMLString(
1271 option, {'2-digit': 'dd', 'numeric': 'd'}); 1280 option, {'2-digit': 'dd', 'numeric': 'd'});
1272 1281
1273 var hr12 = getOption('hour12', 'boolean'); 1282 var hr12 = getOption('hour12', 'boolean');
1274 option = getOption('hour', 'string', ['2-digit', 'numeric']); 1283 option = getOption('hour', 'string', ['2-digit', 'numeric']);
1275 if (hr12 === undefined) { 1284 if (IS_UNDEFINED(hr12)) {
1276 ldmlString += appendToLDMLString(option, {'2-digit': 'jj', 'numeric': 'j'}); 1285 ldmlString += appendToLDMLString(option, {'2-digit': 'jj', 'numeric': 'j'});
1277 } else if (hr12 === true) { 1286 } else if (hr12 === true) {
1278 ldmlString += appendToLDMLString(option, {'2-digit': 'hh', 'numeric': 'h'}); 1287 ldmlString += appendToLDMLString(option, {'2-digit': 'hh', 'numeric': 'h'});
1279 } else { 1288 } else {
1280 ldmlString += appendToLDMLString(option, {'2-digit': 'HH', 'numeric': 'H'}); 1289 ldmlString += appendToLDMLString(option, {'2-digit': 'HH', 'numeric': 'H'});
1281 } 1290 }
1282 1291
1283 option = getOption('minute', 'string', ['2-digit', 'numeric']); 1292 option = getOption('minute', 'string', ['2-digit', 'numeric']);
1284 ldmlString += appendToLDMLString(option, {'2-digit': 'mm', 'numeric': 'm'}); 1293 ldmlString += appendToLDMLString(option, {'2-digit': 'mm', 'numeric': 'm'});
1285 1294
1286 option = getOption('second', 'string', ['2-digit', 'numeric']); 1295 option = getOption('second', 'string', ['2-digit', 'numeric']);
1287 ldmlString += appendToLDMLString(option, {'2-digit': 'ss', 'numeric': 's'}); 1296 ldmlString += appendToLDMLString(option, {'2-digit': 'ss', 'numeric': 's'});
1288 1297
1289 option = getOption('timeZoneName', 'string', ['short', 'long']); 1298 option = getOption('timeZoneName', 'string', ['short', 'long']);
1290 ldmlString += appendToLDMLString(option, {short: 'z', long: 'zzzz'}); 1299 ldmlString += appendToLDMLString(option, {short: 'z', long: 'zzzz'});
1291 1300
1292 return ldmlString; 1301 return ldmlString;
1293 } 1302 }
1294 1303
1295 1304
1296 /** 1305 /**
1297 * Returns either LDML equivalent of the current option or empty string. 1306 * Returns either LDML equivalent of the current option or empty string.
1298 */ 1307 */
1299 function appendToLDMLString(option, pairs) { 1308 function appendToLDMLString(option, pairs) {
1300 if (option !== undefined) { 1309 if (!IS_UNDEFINED(option)) {
1301 return pairs[option]; 1310 return pairs[option];
1302 } else { 1311 } else {
1303 return ''; 1312 return '';
1304 } 1313 }
1305 } 1314 }
1306 1315
1307 1316
1308 /** 1317 /**
1309 * Returns object that matches LDML representation of the date. 1318 * Returns object that matches LDML representation of the date.
1310 */ 1319 */
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 options = appendToDateTimeObject( 1373 options = appendToDateTimeObject(
1365 options, 'timeZoneName', match, {z: 'short', zzzz: 'long'}); 1374 options, 'timeZoneName', match, {z: 'short', zzzz: 'long'});
1366 1375
1367 return options; 1376 return options;
1368 } 1377 }
1369 1378
1370 1379
1371 function appendToDateTimeObject(options, option, match, pairs) { 1380 function appendToDateTimeObject(options, option, match, pairs) {
1372 if (IS_NULL(match)) { 1381 if (IS_NULL(match)) {
1373 if (!options.hasOwnProperty(option)) { 1382 if (!options.hasOwnProperty(option)) {
1374 defineWEProperty(options, option, undefined); 1383 defineWEProperty(options, option, UNDEFINED);
1375 } 1384 }
1376 return options; 1385 return options;
1377 } 1386 }
1378 1387
1379 var property = match[0]; 1388 var property = match[0];
1380 defineWEProperty(options, option, pairs[property]); 1389 defineWEProperty(options, option, pairs[property]);
1381 1390
1382 return options; 1391 return options;
1383 } 1392 }
1384 1393
1385 1394
1386 /** 1395 /**
1387 * Returns options with at least default values in it. 1396 * Returns options with at least default values in it.
1388 */ 1397 */
1389 function toDateTimeOptions(options, required, defaults) { 1398 function toDateTimeOptions(options, required, defaults) {
1390 if (options === undefined) { 1399 if (IS_UNDEFINED(options)) {
1391 options = {}; 1400 options = {};
1392 } else { 1401 } else {
1393 options = TO_OBJECT_INLINE(options); 1402 options = TO_OBJECT_INLINE(options);
1394 } 1403 }
1395 1404
1396 var needsDefault = true; 1405 var needsDefault = true;
1397 if ((required === 'date' || required === 'any') && 1406 if ((required === 'date' || required === 'any') &&
1398 (options.weekday !== undefined || options.year !== undefined || 1407 (!IS_UNDEFINED(options.weekday) || !IS_UNDEFINED(options.year) ||
1399 options.month !== undefined || options.day !== undefined)) { 1408 !IS_UNDEFINED(options.month) || !IS_UNDEFINED(options.day))) {
1400 needsDefault = false; 1409 needsDefault = false;
1401 } 1410 }
1402 1411
1403 if ((required === 'time' || required === 'any') && 1412 if ((required === 'time' || required === 'any') &&
1404 (options.hour !== undefined || options.minute !== undefined || 1413 (!IS_UNDEFINED(options.hour) || !IS_UNDEFINED(options.minute) ||
1405 options.second !== undefined)) { 1414 !IS_UNDEFINED(options.second))) {
1406 needsDefault = false; 1415 needsDefault = false;
1407 } 1416 }
1408 1417
1409 if (needsDefault && (defaults === 'date' || defaults === 'all')) { 1418 if (needsDefault && (defaults === 'date' || defaults === 'all')) {
1410 $objectDefineProperty(options, 'year', {value: 'numeric', 1419 $objectDefineProperty(options, 'year', {value: 'numeric',
1411 writable: true, 1420 writable: true,
1412 enumerable: true, 1421 enumerable: true,
1413 configurable: true}); 1422 configurable: true});
1414 $objectDefineProperty(options, 'month', {value: 'numeric', 1423 $objectDefineProperty(options, 'month', {value: 'numeric',
1415 writable: true, 1424 writable: true,
(...skipping 27 matching lines...) Expand all
1443 /** 1452 /**
1444 * Initializes the given object so it's a valid DateTimeFormat instance. 1453 * Initializes the given object so it's a valid DateTimeFormat instance.
1445 * Useful for subclassing. 1454 * Useful for subclassing.
1446 */ 1455 */
1447 function initializeDateTimeFormat(dateFormat, locales, options) { 1456 function initializeDateTimeFormat(dateFormat, locales, options) {
1448 1457
1449 if (%IsInitializedIntlObject(dateFormat)) { 1458 if (%IsInitializedIntlObject(dateFormat)) {
1450 throw MakeTypeError(kReinitializeIntl, "DateTimeFormat"); 1459 throw MakeTypeError(kReinitializeIntl, "DateTimeFormat");
1451 } 1460 }
1452 1461
1453 if (options === undefined) { 1462 if (IS_UNDEFINED(options)) {
1454 options = {}; 1463 options = {};
1455 } 1464 }
1456 1465
1457 var locale = resolveLocale('dateformat', locales, options); 1466 var locale = resolveLocale('dateformat', locales, options);
1458 1467
1459 options = toDateTimeOptions(options, 'any', 'date'); 1468 options = toDateTimeOptions(options, 'any', 'date');
1460 1469
1461 var getOption = getGetOption(options, 'dateformat'); 1470 var getOption = getGetOption(options, 'dateformat');
1462 1471
1463 // We implement only best fit algorithm, but still need to check 1472 // We implement only best fit algorithm, but still need to check
(...skipping 12 matching lines...) Expand all
1476 // ICU prefers options to be passed using -u- extension key/values, so 1485 // ICU prefers options to be passed using -u- extension key/values, so
1477 // we need to build that. 1486 // we need to build that.
1478 var internalOptions = {}; 1487 var internalOptions = {};
1479 var extensionMap = parseExtension(locale.extension); 1488 var extensionMap = parseExtension(locale.extension);
1480 1489
1481 /** 1490 /**
1482 * Map of Unicode extensions to option properties, and their values and types, 1491 * Map of Unicode extensions to option properties, and their values and types,
1483 * for a date/time format. 1492 * for a date/time format.
1484 */ 1493 */
1485 var DATETIME_FORMAT_KEY_MAP = { 1494 var DATETIME_FORMAT_KEY_MAP = {
1486 'ca': {'property': undefined, 'type': 'string'}, 1495 'ca': {'property': UNDEFINED, 'type': 'string'},
1487 'nu': {'property': undefined, 'type': 'string'} 1496 'nu': {'property': UNDEFINED, 'type': 'string'}
1488 }; 1497 };
1489 1498
1490 var extension = setOptions(options, extensionMap, DATETIME_FORMAT_KEY_MAP, 1499 var extension = setOptions(options, extensionMap, DATETIME_FORMAT_KEY_MAP,
1491 getOption, internalOptions); 1500 getOption, internalOptions);
1492 1501
1493 var requestedLocale = locale.locale + extension; 1502 var requestedLocale = locale.locale + extension;
1494 var resolved = $objectDefineProperties({}, { 1503 var resolved = $objectDefineProperties({}, {
1495 calendar: {writable: true}, 1504 calendar: {writable: true},
1496 day: {writable: true}, 1505 day: {writable: true},
1497 era: {writable: true}, 1506 era: {writable: true},
1498 hour12: {writable: true}, 1507 hour12: {writable: true},
1499 hour: {writable: true}, 1508 hour: {writable: true},
1500 locale: {writable: true}, 1509 locale: {writable: true},
1501 minute: {writable: true}, 1510 minute: {writable: true},
1502 month: {writable: true}, 1511 month: {writable: true},
1503 numberingSystem: {writable: true}, 1512 numberingSystem: {writable: true},
1504 pattern: {writable: true}, 1513 pattern: {writable: true},
1505 requestedLocale: {value: requestedLocale, writable: true}, 1514 requestedLocale: {value: requestedLocale, writable: true},
1506 second: {writable: true}, 1515 second: {writable: true},
1507 timeZone: {writable: true}, 1516 timeZone: {writable: true},
1508 timeZoneName: {writable: true}, 1517 timeZoneName: {writable: true},
1509 tz: {value: tz, writable: true}, 1518 tz: {value: tz, writable: true},
1510 weekday: {writable: true}, 1519 weekday: {writable: true},
1511 year: {writable: true} 1520 year: {writable: true}
1512 }); 1521 });
1513 1522
1514 var formatter = %CreateDateTimeFormat( 1523 var formatter = %CreateDateTimeFormat(
1515 requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved); 1524 requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved);
1516 1525
1517 if (tz !== undefined && tz !== resolved.timeZone) { 1526 if (!IS_UNDEFINED(tz) && tz !== resolved.timeZone) {
1518 throw MakeRangeError(kUnsupportedTimeZone, tz); 1527 throw MakeRangeError(kUnsupportedTimeZone, tz);
1519 } 1528 }
1520 1529
1521 %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter); 1530 %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter);
1522 $objectDefineProperty(dateFormat, 'resolved', {value: resolved}); 1531 $objectDefineProperty(dateFormat, 'resolved', {value: resolved});
1523 1532
1524 return dateFormat; 1533 return dateFormat;
1525 } 1534 }
1526 1535
1527 1536
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 'chinese': 'chinese', 1582 'chinese': 'chinese',
1574 'indian': 'indian', 1583 'indian': 'indian',
1575 'coptic': 'coptic', 1584 'coptic': 'coptic',
1576 'ethiopic': 'ethiopic', 1585 'ethiopic': 'ethiopic',
1577 'ethiopic-amete-alem': 'ethioaa' 1586 'ethiopic-amete-alem': 'ethioaa'
1578 }; 1587 };
1579 1588
1580 var format = this; 1589 var format = this;
1581 var fromPattern = fromLDMLString(format.resolved.pattern); 1590 var fromPattern = fromLDMLString(format.resolved.pattern);
1582 var userCalendar = ICU_CALENDAR_MAP[format.resolved.calendar]; 1591 var userCalendar = ICU_CALENDAR_MAP[format.resolved.calendar];
1583 if (userCalendar === undefined) { 1592 if (IS_UNDEFINED(userCalendar)) {
1584 // Use ICU name if we don't have a match. It shouldn't happen, but 1593 // Use ICU name if we don't have a match. It shouldn't happen, but
1585 // it would be too strict to throw for this. 1594 // it would be too strict to throw for this.
1586 userCalendar = format.resolved.calendar; 1595 userCalendar = format.resolved.calendar;
1587 } 1596 }
1588 1597
1589 var locale = getOptimalLanguageTag(format.resolved.requestedLocale, 1598 var locale = getOptimalLanguageTag(format.resolved.requestedLocale,
1590 format.resolved.locale); 1599 format.resolved.locale);
1591 1600
1592 var result = { 1601 var result = {
1593 locale: locale, 1602 locale: locale,
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 %SetNativeFlag(Intl.DateTimeFormat.supportedLocalesOf); 1646 %SetNativeFlag(Intl.DateTimeFormat.supportedLocalesOf);
1638 1647
1639 1648
1640 /** 1649 /**
1641 * Returns a String value representing the result of calling ToNumber(date) 1650 * Returns a String value representing the result of calling ToNumber(date)
1642 * according to the effective locale and the formatting options of this 1651 * according to the effective locale and the formatting options of this
1643 * DateTimeFormat. 1652 * DateTimeFormat.
1644 */ 1653 */
1645 function formatDate(formatter, dateValue) { 1654 function formatDate(formatter, dateValue) {
1646 var dateMs; 1655 var dateMs;
1647 if (dateValue === undefined) { 1656 if (IS_UNDEFINED(dateValue)) {
1648 dateMs = GlobalDate.now(); 1657 dateMs = GlobalDate.now();
1649 } else { 1658 } else {
1650 dateMs = $toNumber(dateValue); 1659 dateMs = $toNumber(dateValue);
1651 } 1660 }
1652 1661
1653 if (!$isFinite(dateMs)) throw MakeRangeError(kDateRange); 1662 if (!$isFinite(dateMs)) throw MakeRangeError(kDateRange);
1654 1663
1655 return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter), 1664 return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter),
1656 new GlobalDate(dateMs)); 1665 new GlobalDate(dateMs));
1657 } 1666 }
(...skipping 15 matching lines...) Expand all
1673 addBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0); 1682 addBoundMethod(Intl.DateTimeFormat, 'format', formatDate, 0);
1674 addBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1); 1683 addBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
1675 1684
1676 1685
1677 /** 1686 /**
1678 * Returns canonical Area/Location name, or throws an exception if the zone 1687 * Returns canonical Area/Location name, or throws an exception if the zone
1679 * name is invalid IANA name. 1688 * name is invalid IANA name.
1680 */ 1689 */
1681 function canonicalizeTimeZoneID(tzID) { 1690 function canonicalizeTimeZoneID(tzID) {
1682 // Skip undefined zones. 1691 // Skip undefined zones.
1683 if (tzID === undefined) { 1692 if (IS_UNDEFINED(tzID)) {
1684 return tzID; 1693 return tzID;
1685 } 1694 }
1686 1695
1687 // Special case handling (UTC, GMT). 1696 // Special case handling (UTC, GMT).
1688 var upperID = tzID.toUpperCase(); 1697 var upperID = tzID.toUpperCase();
1689 if (upperID === 'UTC' || upperID === 'GMT' || 1698 if (upperID === 'UTC' || upperID === 'GMT' ||
1690 upperID === 'ETC/UTC' || upperID === 'ETC/GMT') { 1699 upperID === 'ETC/UTC' || upperID === 'ETC/GMT') {
1691 return 'UTC'; 1700 return 'UTC';
1692 } 1701 }
1693 1702
1694 // We expect only _ and / beside ASCII letters. 1703 // We expect only _ and / beside ASCII letters.
1695 // All inputs should conform to Area/Location from now on. 1704 // All inputs should conform to Area/Location from now on.
1696 var match = GetTimezoneNameCheckRE().exec(tzID); 1705 var match = GetTimezoneNameCheckRE().exec(tzID);
1697 if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID); 1706 if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID);
1698 1707
1699 var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]); 1708 var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]);
1700 var i = 3; 1709 var i = 3;
1701 while (match[i] !== undefined && i < match.length) { 1710 while (!IS_UNDEFINED(match[i]) && i < match.length) {
1702 result = result + '_' + toTitleCaseWord(match[i]); 1711 result = result + '_' + toTitleCaseWord(match[i]);
1703 i++; 1712 i++;
1704 } 1713 }
1705 1714
1706 return result; 1715 return result;
1707 } 1716 }
1708 1717
1709 /** 1718 /**
1710 * Initializes the given object so it's a valid BreakIterator instance. 1719 * Initializes the given object so it's a valid BreakIterator instance.
1711 * Useful for subclassing. 1720 * Useful for subclassing.
1712 */ 1721 */
1713 function initializeBreakIterator(iterator, locales, options) { 1722 function initializeBreakIterator(iterator, locales, options) {
1714 if (%IsInitializedIntlObject(iterator)) { 1723 if (%IsInitializedIntlObject(iterator)) {
1715 throw MakeTypeError(kReinitializeIntl, "v8BreakIterator"); 1724 throw MakeTypeError(kReinitializeIntl, "v8BreakIterator");
1716 } 1725 }
1717 1726
1718 if (options === undefined) { 1727 if (IS_UNDEFINED(options)) {
1719 options = {}; 1728 options = {};
1720 } 1729 }
1721 1730
1722 var getOption = getGetOption(options, 'breakiterator'); 1731 var getOption = getGetOption(options, 'breakiterator');
1723 1732
1724 var internalOptions = {}; 1733 var internalOptions = {};
1725 1734
1726 defineWEProperty(internalOptions, 'type', getOption( 1735 defineWEProperty(internalOptions, 'type', getOption(
1727 'type', 'string', ['character', 'word', 'sentence', 'line'], 'word')); 1736 'type', 'string', ['character', 'word', 'sentence', 'line'], 'word'));
1728 1737
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1871 'numberformat': Intl.NumberFormat, 1880 'numberformat': Intl.NumberFormat,
1872 'dateformatall': Intl.DateTimeFormat, 1881 'dateformatall': Intl.DateTimeFormat,
1873 'dateformatdate': Intl.DateTimeFormat, 1882 'dateformatdate': Intl.DateTimeFormat,
1874 'dateformattime': Intl.DateTimeFormat 1883 'dateformattime': Intl.DateTimeFormat
1875 }; 1884 };
1876 1885
1877 1886
1878 // Default (created with undefined locales and options parameters) collator, 1887 // Default (created with undefined locales and options parameters) collator,
1879 // number and date format instances. They'll be created as needed. 1888 // number and date format instances. They'll be created as needed.
1880 var defaultObjects = { 1889 var defaultObjects = {
1881 'collator': undefined, 1890 'collator': UNDEFINED,
1882 'numberformat': undefined, 1891 'numberformat': UNDEFINED,
1883 'dateformatall': undefined, 1892 'dateformatall': UNDEFINED,
1884 'dateformatdate': undefined, 1893 'dateformatdate': UNDEFINED,
1885 'dateformattime': undefined, 1894 'dateformattime': UNDEFINED,
1886 }; 1895 };
1887 1896
1888 1897
1889 /** 1898 /**
1890 * Returns cached or newly created instance of a given service. 1899 * Returns cached or newly created instance of a given service.
1891 * We cache only default instances (where no locales or options are provided). 1900 * We cache only default instances (where no locales or options are provided).
1892 */ 1901 */
1893 function cachedOrNewService(service, locales, options, defaults) { 1902 function cachedOrNewService(service, locales, options, defaults) {
1894 var useOptions = (defaults === undefined) ? options : defaults; 1903 var useOptions = (IS_UNDEFINED(defaults)) ? options : defaults;
1895 if (locales === undefined && options === undefined) { 1904 if (IS_UNDEFINED(locales) && IS_UNDEFINED(options)) {
1896 if (defaultObjects[service] === undefined) { 1905 if (IS_UNDEFINED(defaultObjects[service])) {
1897 defaultObjects[service] = new savedObjects[service](locales, useOptions); 1906 defaultObjects[service] = new savedObjects[service](locales, useOptions);
1898 } 1907 }
1899 return defaultObjects[service]; 1908 return defaultObjects[service];
1900 } 1909 }
1901 return new savedObjects[service](locales, useOptions); 1910 return new savedObjects[service](locales, useOptions);
1902 } 1911 }
1903 1912
1904 1913
1905 /** 1914 /**
1906 * Compares this and that, and returns less than 0, 0 or greater than 0 value. 1915 * Compares this and that, and returns less than 0, 0 or greater than 0 value.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2040 } 2049 }
2041 2050
2042 var locales = %_Arguments(0); 2051 var locales = %_Arguments(0);
2043 var options = %_Arguments(1); 2052 var options = %_Arguments(1);
2044 return toLocaleDateTime( 2053 return toLocaleDateTime(
2045 this, locales, options, 'time', 'time', 'dateformattime'); 2054 this, locales, options, 'time', 'time', 'dateformattime');
2046 } 2055 }
2047 ); 2056 );
2048 2057
2049 }) 2058 })
OLDNEW
« no previous file with comments | « src/harmony-typedarray.js ('k') | src/iterator-prototype.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698