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

Side by Side Diff: src/i18n.js

Issue 1199813004: i18n.js was not using original functions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Use match instead of exec Created 5 years, 6 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/array.js ('k') | src/regexp.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, utils) { 11 (function(global, utils) {
12 12
13 "use strict"; 13 "use strict";
14 14
15 %CheckIsBootstrapping(); 15 %CheckIsBootstrapping();
16 16
17 // ------------------------------------------------------------------- 17 // -------------------------------------------------------------------
18 // Imports 18 // Imports
19 19
20 var GlobalBoolean = global.Boolean; 20 var GlobalBoolean = global.Boolean;
21 var GlobalDate = global.Date; 21 var GlobalDate = global.Date;
22 var GlobalNumber = global.Number; 22 var GlobalNumber = global.Number;
23 var GlobalRegExp = global.RegExp; 23 var GlobalRegExp = global.RegExp;
24 var GlobalString = global.String; 24 var GlobalString = global.String;
25 var ObjectDefineProperties = utils.ObjectDefineProperties; 25 var ObjectDefineProperties = utils.ObjectDefineProperties;
26 var ObjectDefineProperty = utils.ObjectDefineProperty; 26 var ObjectDefineProperty = utils.ObjectDefineProperty;
27 var SetFunctionName = utils.SetFunctionName; 27 var SetFunctionName = utils.SetFunctionName;
28 28
29 var ArrayIndexOf;
30 var ArrayJoin;
29 var IsFinite; 31 var IsFinite;
30 var IsNaN; 32 var IsNaN;
31 var MathFloor; 33 var MathFloor;
34 var RegExpTest;
35 var StringIndexOf;
36 var StringLastIndexOf;
37 var StringMatch;
38 var StringReplace;
39 var StringSplit;
40 var StringSubstr;
41 var StringSubstring;
32 42
33 utils.Import(function(from) { 43 utils.Import(function(from) {
44 ArrayIndexOf = from.ArrayIndexOf;
45 ArrayJoin = from.ArrayJoin;
34 IsFinite = from.IsFinite; 46 IsFinite = from.IsFinite;
35 IsNaN = from.IsNaN; 47 IsNaN = from.IsNaN;
36 MathFloor = from.MathFloor; 48 MathFloor = from.MathFloor;
49 RegExpTest = from.RegExpTest;
50 StringIndexOf = from.StringIndexOf;
51 StringLastIndexOf = from.StringLastIndexOf;
52 StringMatch = from.StringMatch;
53 StringReplace = from.StringReplace;
54 StringSplit = from.StringSplit;
55 StringSubstr = from.StringSubstr;
56 StringSubstring = from.StringSubstring;
37 }); 57 });
38 58
39 // ------------------------------------------------------------------- 59 // -------------------------------------------------------------------
40 60
41 var Intl = {}; 61 var Intl = {};
42 62
43 %AddNamedProperty(global, "Intl", Intl, DONT_ENUM); 63 %AddNamedProperty(global, "Intl", Intl, DONT_ENUM);
44 64
45 /** 65 /**
46 * Caches available locales for each service. 66 * Caches available locales for each service.
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 configurable: true 236 configurable: true
217 }); 237 });
218 } 238 }
219 239
220 240
221 /** 241 /**
222 * Returns an intersection of locales and service supported locales. 242 * Returns an intersection of locales and service supported locales.
223 * Parameter locales is treated as a priority list. 243 * Parameter locales is treated as a priority list.
224 */ 244 */
225 function supportedLocalesOf(service, locales, options) { 245 function supportedLocalesOf(service, locales, options) {
226 if (IS_NULL(service.match(GetServiceRE()))) { 246 if (IS_NULL(%_CallFunction(service, GetServiceRE(), StringMatch))) {
227 throw MakeError(kWrongServiceType, service); 247 throw MakeError(kWrongServiceType, service);
228 } 248 }
229 249
230 // Provide defaults if matcher was not specified. 250 // Provide defaults if matcher was not specified.
231 if (IS_UNDEFINED(options)) { 251 if (IS_UNDEFINED(options)) {
232 options = {}; 252 options = {};
233 } else { 253 } else {
234 options = $toObject(options); 254 options = $toObject(options);
235 } 255 }
236 256
(...skipping 27 matching lines...) Expand all
264 284
265 /** 285 /**
266 * Returns the subset of the provided BCP 47 language priority list for which 286 * Returns the subset of the provided BCP 47 language priority list for which
267 * this service has a matching locale when using the BCP 47 Lookup algorithm. 287 * this service has a matching locale when using the BCP 47 Lookup algorithm.
268 * Locales appear in the same order in the returned list as in the input list. 288 * Locales appear in the same order in the returned list as in the input list.
269 */ 289 */
270 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { 290 function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
271 var matchedLocales = []; 291 var matchedLocales = [];
272 for (var i = 0; i < requestedLocales.length; ++i) { 292 for (var i = 0; i < requestedLocales.length; ++i) {
273 // Remove -u- extension. 293 // Remove -u- extension.
274 var locale = requestedLocales[i].replace(GetUnicodeExtensionRE(), ''); 294 var locale = %_CallFunction(requestedLocales[i], GetUnicodeExtensionRE(),
295 '', StringReplace);
275 do { 296 do {
276 if (!IS_UNDEFINED(availableLocales[locale])) { 297 if (!IS_UNDEFINED(availableLocales[locale])) {
277 // Push requested locale not the resolved one. 298 // Push requested locale not the resolved one.
278 matchedLocales.push(requestedLocales[i]); 299 %_CallFunction(matchedLocales, requestedLocales[i], $arrayPush);
279 break; 300 break;
280 } 301 }
281 // Truncate locale if possible, if not break. 302 // Truncate locale if possible, if not break.
282 var pos = locale.lastIndexOf('-'); 303 var pos = %_CallFunction(locale, '-', StringLastIndexOf);
283 if (pos === -1) { 304 if (pos === -1) {
284 break; 305 break;
285 } 306 }
286 locale = locale.substring(0, pos); 307 locale = %_CallFunction(locale, 0, pos, StringSubstring);
287 } while (true); 308 } while (true);
288 } 309 }
289 310
290 return matchedLocales; 311 return matchedLocales;
291 } 312 }
292 313
293 314
294 /** 315 /**
295 * Returns the subset of the provided BCP 47 language priority list for which 316 * Returns the subset of the provided BCP 47 language priority list for which
296 * this service has a matching locale when using the implementation 317 * this service has a matching locale when using the implementation
(...skipping 23 matching lines...) Expand all
320 break; 341 break;
321 case 'string': 342 case 'string':
322 value = GlobalString(value); 343 value = GlobalString(value);
323 break; 344 break;
324 case 'number': 345 case 'number':
325 value = GlobalNumber(value); 346 value = GlobalNumber(value);
326 break; 347 break;
327 default: 348 default:
328 throw MakeError(kWrongValueType); 349 throw MakeError(kWrongValueType);
329 } 350 }
330 if (!IS_UNDEFINED(values) && values.indexOf(value) === -1) { 351
352 if (!IS_UNDEFINED(values) &&
353 %_CallFunction(values, value, ArrayIndexOf) === -1) {
331 throw MakeRangeError(kValueOutOfRange, value, caller, property); 354 throw MakeRangeError(kValueOutOfRange, value, caller, property);
332 } 355 }
333 356
334 return value; 357 return value;
335 } 358 }
336 359
337 return defaultValue; 360 return defaultValue;
338 } 361 }
339 362
340 return getOption; 363 return getOption;
(...skipping 28 matching lines...) Expand all
369 392
370 return resolved; 393 return resolved;
371 } 394 }
372 395
373 396
374 /** 397 /**
375 * Returns best matched supported locale and extension info using basic 398 * Returns best matched supported locale and extension info using basic
376 * lookup algorithm. 399 * lookup algorithm.
377 */ 400 */
378 function lookupMatcher(service, requestedLocales) { 401 function lookupMatcher(service, requestedLocales) {
379 if (IS_NULL(service.match(GetServiceRE()))) { 402 if (IS_NULL(%_CallFunction(service, GetServiceRE(), StringMatch))) {
380 throw MakeError(kWrongServiceType, service); 403 throw MakeError(kWrongServiceType, service);
381 } 404 }
382 405
383 // Cache these, they don't ever change per service. 406 // Cache these, they don't ever change per service.
384 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) { 407 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) {
385 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); 408 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service);
386 } 409 }
387 410
388 for (var i = 0; i < requestedLocales.length; ++i) { 411 for (var i = 0; i < requestedLocales.length; ++i) {
389 // Remove all extensions. 412 // Remove all extensions.
390 var locale = requestedLocales[i].replace(GetAnyExtensionRE(), ''); 413 var locale = %_CallFunction(requestedLocales[i], GetAnyExtensionRE(), '',
414 StringReplace);
391 do { 415 do {
392 if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) { 416 if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) {
393 // Return the resolved locale and extension. 417 // Return the resolved locale and extension.
394 var extensionMatch = requestedLocales[i].match(GetUnicodeExtensionRE()); 418 var extensionMatch =
419 %_CallFunction(requestedLocales[i], GetUnicodeExtensionRE(),
420 StringMatch);
395 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; 421 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0];
396 return {'locale': locale, 'extension': extension, 'position': i}; 422 return {'locale': locale, 'extension': extension, 'position': i};
397 } 423 }
398 // Truncate locale if possible. 424 // Truncate locale if possible.
399 var pos = locale.lastIndexOf('-'); 425 var pos = %_CallFunction(locale, '-', StringLastIndexOf);
400 if (pos === -1) { 426 if (pos === -1) {
401 break; 427 break;
402 } 428 }
403 locale = locale.substring(0, pos); 429 locale = %_CallFunction(locale, 0, pos, StringSubstring);
404 } while (true); 430 } while (true);
405 } 431 }
406 432
407 // Didn't find a match, return default. 433 // Didn't find a match, return default.
408 if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) { 434 if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
409 DEFAULT_ICU_LOCALE = %GetDefaultICULocale(); 435 DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
410 } 436 }
411 437
412 return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1}; 438 return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
413 } 439 }
414 440
415 441
416 /** 442 /**
417 * Returns best matched supported locale and extension info using 443 * Returns best matched supported locale and extension info using
418 * implementation dependend algorithm. 444 * implementation dependend algorithm.
419 */ 445 */
420 function bestFitMatcher(service, requestedLocales) { 446 function bestFitMatcher(service, requestedLocales) {
421 // TODO(cira): implement better best fit algorithm. 447 // TODO(cira): implement better best fit algorithm.
422 return lookupMatcher(service, requestedLocales); 448 return lookupMatcher(service, requestedLocales);
423 } 449 }
424 450
425 451
426 /** 452 /**
427 * Parses Unicode extension into key - value map. 453 * Parses Unicode extension into key - value map.
428 * Returns empty object if the extension string is invalid. 454 * Returns empty object if the extension string is invalid.
429 * We are not concerned with the validity of the values at this point. 455 * We are not concerned with the validity of the values at this point.
430 */ 456 */
431 function parseExtension(extension) { 457 function parseExtension(extension) {
432 var extensionSplit = extension.split('-'); 458 var extensionSplit = %_CallFunction(extension, '-', StringSplit);
433 459
434 // Assume ['', 'u', ...] input, but don't throw. 460 // Assume ['', 'u', ...] input, but don't throw.
435 if (extensionSplit.length <= 2 || 461 if (extensionSplit.length <= 2 ||
436 (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) { 462 (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) {
437 return {}; 463 return {};
438 } 464 }
439 465
440 // Key is {2}alphanum, value is {3,8}alphanum. 466 // Key is {2}alphanum, value is {3,8}alphanum.
441 // Some keys may not have explicit values (booleans). 467 // Some keys may not have explicit values (booleans).
442 var extensionMap = {}; 468 var extensionMap = {};
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 if (type === 'boolean' && (typeof value === 'string')) { 507 if (type === 'boolean' && (typeof value === 'string')) {
482 value = (value === 'true') ? true : false; 508 value = (value === 'true') ? true : false;
483 } 509 }
484 510
485 if (!IS_UNDEFINED(property)) { 511 if (!IS_UNDEFINED(property)) {
486 defineWEProperty(outOptions, property, value); 512 defineWEProperty(outOptions, property, value);
487 } 513 }
488 } 514 }
489 515
490 for (var key in keyValues) { 516 for (var key in keyValues) {
491 if (keyValues.hasOwnProperty(key)) { 517 if (%HasOwnProperty(keyValues, key)) {
492 var value = UNDEFINED; 518 var value = UNDEFINED;
493 var map = keyValues[key]; 519 var map = keyValues[key];
494 if (!IS_UNDEFINED(map.property)) { 520 if (!IS_UNDEFINED(map.property)) {
495 // This may return true if user specifies numeric: 'false', since 521 // This may return true if user specifies numeric: 'false', since
496 // Boolean('nonempty') === true. 522 // Boolean('nonempty') === true.
497 value = getOption(map.property, map.type, map.values); 523 value = getOption(map.property, map.type, map.values);
498 } 524 }
499 if (!IS_UNDEFINED(value)) { 525 if (!IS_UNDEFINED(value)) {
500 updateProperty(map.property, map.type, value); 526 updateProperty(map.property, map.type, value);
501 extension += updateExtension(key, value); 527 extension += updateExtension(key, value);
502 continue; 528 continue;
503 } 529 }
504 // User options didn't have it, check Unicode extension. 530 // User options didn't have it, check Unicode extension.
505 // Here we want to convert strings 'true', 'false' into proper Boolean 531 // Here we want to convert strings 'true', 'false' into proper Boolean
506 // values (not a user error). 532 // values (not a user error).
507 if (extensionMap.hasOwnProperty(key)) { 533 if (%HasOwnProperty(extensionMap, key)) {
508 value = extensionMap[key]; 534 value = extensionMap[key];
509 if (!IS_UNDEFINED(value)) { 535 if (!IS_UNDEFINED(value)) {
510 updateProperty(map.property, map.type, value); 536 updateProperty(map.property, map.type, value);
511 extension += updateExtension(key, value); 537 extension += updateExtension(key, value);
512 } else if (map.type === 'boolean') { 538 } else if (map.type === 'boolean') {
513 // Boolean keys are allowed not to have values in Unicode extension. 539 // Boolean keys are allowed not to have values in Unicode extension.
514 // Those default to true. 540 // Those default to true.
515 updateProperty(map.property, map.type, true); 541 updateProperty(map.property, map.type, true);
516 extension += updateExtension(key, true); 542 extension += updateExtension(key, true);
517 } 543 }
518 } 544 }
519 } 545 }
520 } 546 }
521 547
522 return extension === ''? '' : '-u' + extension; 548 return extension === ''? '' : '-u' + extension;
523 } 549 }
524 550
525 551
526 /** 552 /**
527 * Converts all OwnProperties into 553 * Converts all OwnProperties into
528 * configurable: false, writable: false, enumerable: true. 554 * configurable: false, writable: false, enumerable: true.
529 */ 555 */
530 function freezeArray(array) { 556 function freezeArray(array) {
531 array.forEach(function(element, index) { 557 var l = array.length;
532 ObjectDefineProperty(array, index, {value: element, 558 for (var i = 0; i < l; i++) {
533 configurable: false, 559 if (i in array) {
534 writable: false, 560 ObjectDefineProperty(array, i, {value: array[i],
535 enumerable: true}); 561 configurable: false,
536 }); 562 writable: false,
563 enumerable: true});
564 }
565 }
537 566
538 ObjectDefineProperty(array, 'length', {value: array.length, 567 ObjectDefineProperty(array, 'length', {value: l, writable: false});
539 writable: false});
540 return array; 568 return array;
541 } 569 }
542 570
543 571
544 /** 572 /**
545 * It's sometimes desireable to leave user requested locale instead of ICU 573 * It's sometimes desireable to leave user requested locale instead of ICU
546 * supported one (zh-TW is equivalent to zh-Hant-TW, so we should keep shorter 574 * supported one (zh-TW is equivalent to zh-Hant-TW, so we should keep shorter
547 * one, if that was what user requested). 575 * one, if that was what user requested).
548 * This function returns user specified tag if its maximized form matches ICU 576 * This function returns user specified tag if its maximized form matches ICU
549 * resolved locale. If not we return ICU result. 577 * resolved locale. If not we return ICU result.
550 */ 578 */
551 function getOptimalLanguageTag(original, resolved) { 579 function getOptimalLanguageTag(original, resolved) {
552 // Returns Array<Object>, where each object has maximized and base properties. 580 // Returns Array<Object>, where each object has maximized and base properties.
553 // Maximized: zh -> zh-Hans-CN 581 // Maximized: zh -> zh-Hans-CN
554 // Base: zh-CN-u-ca-gregory -> zh-CN 582 // Base: zh-CN-u-ca-gregory -> zh-CN
555 // Take care of grandfathered or simple cases. 583 // Take care of grandfathered or simple cases.
556 if (original === resolved) { 584 if (original === resolved) {
557 return original; 585 return original;
558 } 586 }
559 587
560 var locales = %GetLanguageTagVariants([original, resolved]); 588 var locales = %GetLanguageTagVariants([original, resolved]);
561 if (locales[0].maximized !== locales[1].maximized) { 589 if (locales[0].maximized !== locales[1].maximized) {
562 return resolved; 590 return resolved;
563 } 591 }
564 592
565 // Preserve extensions of resolved locale, but swap base tags with original. 593 // Preserve extensions of resolved locale, but swap base tags with original.
566 var resolvedBase = new GlobalRegExp('^' + locales[1].base); 594 var resolvedBase = new GlobalRegExp('^' + locales[1].base);
567 return resolved.replace(resolvedBase, locales[0].base); 595 return %_CallFunction(resolved, resolvedBase, locales[0].base, StringReplace);
568 } 596 }
569 597
570 598
571 /** 599 /**
572 * Returns an Object that contains all of supported locales for a given 600 * Returns an Object that contains all of supported locales for a given
573 * service. 601 * service.
574 * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ 602 * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ
575 * that is supported. This is required by the spec. 603 * that is supported. This is required by the spec.
576 */ 604 */
577 function getAvailableLocalesOf(service) { 605 function getAvailableLocalesOf(service) {
578 var available = %AvailableLocalesOf(service); 606 var available = %AvailableLocalesOf(service);
579 607
580 for (var i in available) { 608 for (var i in available) {
581 if (available.hasOwnProperty(i)) { 609 if (%HasOwnProperty(available, i)) {
582 var parts = i.match(/^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/); 610 var parts = %_CallFunction(i, /^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/,
611 StringMatch);
583 if (parts !== null) { 612 if (parts !== null) {
584 // Build xx-ZZ. We don't care about the actual value, 613 // Build xx-ZZ. We don't care about the actual value,
585 // as long it's not undefined. 614 // as long it's not undefined.
586 available[parts[1] + '-' + parts[3]] = null; 615 available[parts[1] + '-' + parts[3]] = null;
587 } 616 }
588 } 617 }
589 } 618 }
590 619
591 return available; 620 return available;
592 } 621 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 if (!IS_UNDEFINED(value)) { 661 if (!IS_UNDEFINED(value)) {
633 defineWECProperty(object, property, value); 662 defineWECProperty(object, property, value);
634 } 663 }
635 } 664 }
636 665
637 666
638 /** 667 /**
639 * Returns titlecased word, aMeRricA -> America. 668 * Returns titlecased word, aMeRricA -> America.
640 */ 669 */
641 function toTitleCaseWord(word) { 670 function toTitleCaseWord(word) {
642 return word.substr(0, 1).toUpperCase() + word.substr(1).toLowerCase(); 671 return %StringToUpperCase(%_CallFunction(word, 0, 1, StringSubstr)) +
672 %StringToLowerCase(%_CallFunction(word, 1, StringSubstr));
643 } 673 }
644 674
645 /** 675 /**
646 * Canonicalizes the language tag, or throws in case the tag is invalid. 676 * Canonicalizes the language tag, or throws in case the tag is invalid.
647 */ 677 */
648 function canonicalizeLanguageTag(localeID) { 678 function canonicalizeLanguageTag(localeID) {
649 // null is typeof 'object' so we have to do extra check. 679 // null is typeof 'object' so we have to do extra check.
650 if (typeof localeID !== 'string' && typeof localeID !== 'object' || 680 if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
651 IS_NULL(localeID)) { 681 IS_NULL(localeID)) {
652 throw MakeTypeError(kLanguageID); 682 throw MakeTypeError(kLanguageID);
(...skipping 23 matching lines...) Expand all
676 * Throws on locales that are not well formed BCP47 tags. 706 * Throws on locales that are not well formed BCP47 tags.
677 */ 707 */
678 function initializeLocaleList(locales) { 708 function initializeLocaleList(locales) {
679 var seen = []; 709 var seen = [];
680 if (IS_UNDEFINED(locales)) { 710 if (IS_UNDEFINED(locales)) {
681 // Constructor is called without arguments. 711 // Constructor is called without arguments.
682 seen = []; 712 seen = [];
683 } else { 713 } else {
684 // We allow single string localeID. 714 // We allow single string localeID.
685 if (typeof locales === 'string') { 715 if (typeof locales === 'string') {
686 seen.push(canonicalizeLanguageTag(locales)); 716 %_CallFunction(seen, canonicalizeLanguageTag(locales), $arrayPush);
687 return freezeArray(seen); 717 return freezeArray(seen);
688 } 718 }
689 719
690 var o = $toObject(locales); 720 var o = $toObject(locales);
691 // Converts it to UInt32 (>>> is shr on 32bit integers). 721 var len = TO_UINT32(o.length);
692 var len = o.length >>> 0;
693 722
694 for (var k = 0; k < len; k++) { 723 for (var k = 0; k < len; k++) {
695 if (k in o) { 724 if (k in o) {
696 var value = o[k]; 725 var value = o[k];
697 726
698 var tag = canonicalizeLanguageTag(value); 727 var tag = canonicalizeLanguageTag(value);
699 728
700 if (seen.indexOf(tag) === -1) { 729 if (%_CallFunction(seen, tag, ArrayIndexOf) === -1) {
701 seen.push(tag); 730 %_CallFunction(seen, tag, $arrayPush);
702 } 731 }
703 } 732 }
704 } 733 }
705 } 734 }
706 735
707 return freezeArray(seen); 736 return freezeArray(seen);
708 } 737 }
709 738
710 739
711 /** 740 /**
712 * Validates the language tag. Section 2.2.9 of the bcp47 spec 741 * Validates the language tag. Section 2.2.9 of the bcp47 spec
713 * defines a valid tag. 742 * defines a valid tag.
714 * 743 *
715 * ICU is too permissible and lets invalid tags, like 744 * ICU is too permissible and lets invalid tags, like
716 * hant-cmn-cn, through. 745 * hant-cmn-cn, through.
717 * 746 *
718 * Returns false if the language tag is invalid. 747 * Returns false if the language tag is invalid.
719 */ 748 */
720 function isValidLanguageTag(locale) { 749 function isValidLanguageTag(locale) {
721 // Check if it's well-formed, including grandfadered tags. 750 // Check if it's well-formed, including grandfadered tags.
722 if (GetLanguageTagRE().test(locale) === false) { 751 if (!%_CallFunction(GetLanguageTagRE(), locale, RegExpTest)) {
723 return false; 752 return false;
724 } 753 }
725 754
726 // Just return if it's a x- form. It's all private. 755 // Just return if it's a x- form. It's all private.
727 if (locale.indexOf('x-') === 0) { 756 if (%_CallFunction(locale, 'x-', StringIndexOf) === 0) {
728 return true; 757 return true;
729 } 758 }
730 759
731 // Check if there are any duplicate variants or singletons (extensions). 760 // Check if there are any duplicate variants or singletons (extensions).
732 761
733 // Remove private use section. 762 // Remove private use section.
734 locale = locale.split(/-x-/)[0]; 763 locale = %_CallFunction(locale, /-x-/, StringSplit)[0];
735 764
736 // Skip language since it can match variant regex, so we start from 1. 765 // Skip language since it can match variant regex, so we start from 1.
737 // We are matching i-klingon here, but that's ok, since i-klingon-klingon 766 // We are matching i-klingon here, but that's ok, since i-klingon-klingon
738 // is not valid and would fail LANGUAGE_TAG_RE test. 767 // is not valid and would fail LANGUAGE_TAG_RE test.
739 var variants = []; 768 var variants = [];
740 var extensions = []; 769 var extensions = [];
741 var parts = locale.split(/-/); 770 var parts = %_CallFunction(locale, /-/, StringSplit);
742 for (var i = 1; i < parts.length; i++) { 771 for (var i = 1; i < parts.length; i++) {
743 var value = parts[i]; 772 var value = parts[i];
744 if (GetLanguageVariantRE().test(value) === true && extensions.length === 0) { 773 if (%_CallFunction(GetLanguageVariantRE(), value, RegExpTest) &&
745 if (variants.indexOf(value) === -1) { 774 extensions.length === 0) {
746 variants.push(value); 775 if (%_CallFunction(variants, value, ArrayIndexOf) === -1) {
776 %_CallFunction(variants, value, $arrayPush);
747 } else { 777 } else {
748 return false; 778 return false;
749 } 779 }
750 } 780 }
751 781
752 if (GetLanguageSingletonRE().test(value) === true) { 782 if (%_CallFunction(GetLanguageSingletonRE(), value, RegExpTest)) {
753 if (extensions.indexOf(value) === -1) { 783 if (%_CallFunction(extensions, value, ArrayIndexOf) === -1) {
754 extensions.push(value); 784 %_CallFunction(extensions, value, $arrayPush);
755 } else { 785 } else {
756 return false; 786 return false;
757 } 787 }
758 } 788 }
759 } 789 }
760 790
761 return true; 791 return true;
762 } 792 }
763 793
764 794
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
847 'kn': {'property': 'numeric', 'type': 'boolean'}, 877 'kn': {'property': 'numeric', 'type': 'boolean'},
848 'kf': {'property': 'caseFirst', 'type': 'string', 878 'kf': {'property': 'caseFirst', 'type': 'string',
849 'values': ['false', 'lower', 'upper']} 879 'values': ['false', 'lower', 'upper']}
850 }; 880 };
851 881
852 setOptions( 882 setOptions(
853 options, extensionMap, COLLATOR_KEY_MAP, getOption, internalOptions); 883 options, extensionMap, COLLATOR_KEY_MAP, getOption, internalOptions);
854 884
855 var collation = 'default'; 885 var collation = 'default';
856 var extension = ''; 886 var extension = '';
857 if (extensionMap.hasOwnProperty('co') && internalOptions.usage === 'sort') { 887 if (%HasOwnProperty(extensionMap, 'co') && internalOptions.usage === 'sort') {
858 888
859 /** 889 /**
860 * Allowed -u-co- values. List taken from: 890 * Allowed -u-co- values. List taken from:
861 * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml 891 * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml
862 */ 892 */
863 var ALLOWED_CO_VALUES = [ 893 var ALLOWED_CO_VALUES = [
864 'big5han', 'dict', 'direct', 'ducet', 'gb2312', 'phonebk', 'phonetic', 894 'big5han', 'dict', 'direct', 'ducet', 'gb2312', 'phonebk', 'phonetic',
865 'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin' 895 'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin'
866 ]; 896 ];
867 897
868 if (ALLOWED_CO_VALUES.indexOf(extensionMap.co) !== -1) { 898 if (%_CallFunction(ALLOWED_CO_VALUES, extensionMap.co, ArrayIndexOf) !==
899 -1) {
869 extension = '-u-co-' + extensionMap.co; 900 extension = '-u-co-' + extensionMap.co;
870 // ICU can't tell us what the collation is, so save user's input. 901 // ICU can't tell us what the collation is, so save user's input.
871 collation = extensionMap.co; 902 collation = extensionMap.co;
872 } 903 }
873 } else if (internalOptions.usage === 'search') { 904 } else if (internalOptions.usage === 'search') {
874 extension = '-u-co-search'; 905 extension = '-u-co-search';
875 } 906 }
876 defineWEProperty(internalOptions, 'collation', collation); 907 defineWEProperty(internalOptions, 'collation', collation);
877 908
878 var requestedLocale = locale.locale + extension; 909 var requestedLocale = locale.locale + extension;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
998 addBoundMethod(Intl.Collator, 'compare', compare, 2); 1029 addBoundMethod(Intl.Collator, 'compare', compare, 2);
999 1030
1000 /** 1031 /**
1001 * Verifies that the input is a well-formed ISO 4217 currency code. 1032 * Verifies that the input is a well-formed ISO 4217 currency code.
1002 * Don't uppercase to test. It could convert invalid code into a valid one. 1033 * Don't uppercase to test. It could convert invalid code into a valid one.
1003 * For example \u00DFP (Eszett+P) becomes SSP. 1034 * For example \u00DFP (Eszett+P) becomes SSP.
1004 */ 1035 */
1005 function isWellFormedCurrencyCode(currency) { 1036 function isWellFormedCurrencyCode(currency) {
1006 return typeof currency == "string" && 1037 return typeof currency == "string" &&
1007 currency.length == 3 && 1038 currency.length == 3 &&
1008 currency.match(/[^A-Za-z]/) == null; 1039 %_CallFunction(currency, /[^A-Za-z]/, StringMatch) == null;
1009 } 1040 }
1010 1041
1011 1042
1012 /** 1043 /**
1013 * Returns the valid digit count for a property, or throws RangeError on 1044 * Returns the valid digit count for a property, or throws RangeError on
1014 * a value out of the range. 1045 * a value out of the range.
1015 */ 1046 */
1016 function getNumberOption(options, property, min, max, fallback) { 1047 function getNumberOption(options, property, min, max, fallback) {
1017 var value = options[property]; 1048 var value = options[property];
1018 if (!IS_UNDEFINED(value)) { 1049 if (!IS_UNDEFINED(value)) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 throw MakeRangeError(kInvalidCurrencyCode, currency); 1084 throw MakeRangeError(kInvalidCurrencyCode, currency);
1054 } 1085 }
1055 1086
1056 if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) { 1087 if (internalOptions.style === 'currency' && IS_UNDEFINED(currency)) {
1057 throw MakeTypeError(kCurrencyCode); 1088 throw MakeTypeError(kCurrencyCode);
1058 } 1089 }
1059 1090
1060 var currencyDisplay = getOption( 1091 var currencyDisplay = getOption(
1061 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol'); 1092 'currencyDisplay', 'string', ['code', 'symbol', 'name'], 'symbol');
1062 if (internalOptions.style === 'currency') { 1093 if (internalOptions.style === 'currency') {
1063 defineWEProperty(internalOptions, 'currency', currency.toUpperCase()); 1094 defineWEProperty(internalOptions, 'currency', %StringToUpperCase(currency));
1064 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay); 1095 defineWEProperty(internalOptions, 'currencyDisplay', currencyDisplay);
1065 } 1096 }
1066 1097
1067 // Digit ranges. 1098 // Digit ranges.
1068 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1); 1099 var mnid = getNumberOption(options, 'minimumIntegerDigits', 1, 21, 1);
1069 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid); 1100 defineWEProperty(internalOptions, 'minimumIntegerDigits', mnid);
1070 1101
1071 var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0); 1102 var mnfd = getNumberOption(options, 'minimumFractionDigits', 0, 20, 0);
1072 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd); 1103 defineWEProperty(internalOptions, 'minimumFractionDigits', mnfd);
1073 1104
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 currencyDisplay: {writable: true}, 1140 currencyDisplay: {writable: true},
1110 locale: {writable: true}, 1141 locale: {writable: true},
1111 maximumFractionDigits: {writable: true}, 1142 maximumFractionDigits: {writable: true},
1112 minimumFractionDigits: {writable: true}, 1143 minimumFractionDigits: {writable: true},
1113 minimumIntegerDigits: {writable: true}, 1144 minimumIntegerDigits: {writable: true},
1114 numberingSystem: {writable: true}, 1145 numberingSystem: {writable: true},
1115 requestedLocale: {value: requestedLocale, writable: true}, 1146 requestedLocale: {value: requestedLocale, writable: true},
1116 style: {value: internalOptions.style, writable: true}, 1147 style: {value: internalOptions.style, writable: true},
1117 useGrouping: {writable: true} 1148 useGrouping: {writable: true}
1118 }); 1149 });
1119 if (internalOptions.hasOwnProperty('minimumSignificantDigits')) { 1150 if (%HasOwnProperty(internalOptions, 'minimumSignificantDigits')) {
1120 defineWEProperty(resolved, 'minimumSignificantDigits', UNDEFINED); 1151 defineWEProperty(resolved, 'minimumSignificantDigits', UNDEFINED);
1121 } 1152 }
1122 if (internalOptions.hasOwnProperty('maximumSignificantDigits')) { 1153 if (%HasOwnProperty(internalOptions, 'maximumSignificantDigits')) {
1123 defineWEProperty(resolved, 'maximumSignificantDigits', UNDEFINED); 1154 defineWEProperty(resolved, 'maximumSignificantDigits', UNDEFINED);
1124 } 1155 }
1125 var formatter = %CreateNumberFormat(requestedLocale, 1156 var formatter = %CreateNumberFormat(requestedLocale,
1126 internalOptions, 1157 internalOptions,
1127 resolved); 1158 resolved);
1128 1159
1129 // We can't get information about number or currency style from ICU, so we 1160 // We can't get information about number or currency style from ICU, so we
1130 // assume user request was fulfilled. 1161 // assume user request was fulfilled.
1131 if (internalOptions.style === 'currency') { 1162 if (internalOptions.style === 'currency') {
1132 ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay, 1163 ObjectDefineProperty(resolved, 'currencyDisplay', {value: currencyDisplay,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 minimumFractionDigits: format.resolved.minimumFractionDigits, 1217 minimumFractionDigits: format.resolved.minimumFractionDigits,
1187 maximumFractionDigits: format.resolved.maximumFractionDigits, 1218 maximumFractionDigits: format.resolved.maximumFractionDigits,
1188 }; 1219 };
1189 1220
1190 if (result.style === 'currency') { 1221 if (result.style === 'currency') {
1191 defineWECProperty(result, 'currency', format.resolved.currency); 1222 defineWECProperty(result, 'currency', format.resolved.currency);
1192 defineWECProperty(result, 'currencyDisplay', 1223 defineWECProperty(result, 'currencyDisplay',
1193 format.resolved.currencyDisplay); 1224 format.resolved.currencyDisplay);
1194 } 1225 }
1195 1226
1196 if (format.resolved.hasOwnProperty('minimumSignificantDigits')) { 1227 if (%HasOwnProperty(format.resolved, 'minimumSignificantDigits')) {
1197 defineWECProperty(result, 'minimumSignificantDigits', 1228 defineWECProperty(result, 'minimumSignificantDigits',
1198 format.resolved.minimumSignificantDigits); 1229 format.resolved.minimumSignificantDigits);
1199 } 1230 }
1200 1231
1201 if (format.resolved.hasOwnProperty('maximumSignificantDigits')) { 1232 if (%HasOwnProperty(format.resolved, 'maximumSignificantDigits')) {
1202 defineWECProperty(result, 'maximumSignificantDigits', 1233 defineWECProperty(result, 'maximumSignificantDigits',
1203 format.resolved.maximumSignificantDigits); 1234 format.resolved.maximumSignificantDigits);
1204 } 1235 }
1205 1236
1206 return result; 1237 return result;
1207 }, 1238 },
1208 DONT_ENUM 1239 DONT_ENUM
1209 ); 1240 );
1210 SetFunctionName(Intl.NumberFormat.prototype.resolvedOptions, 'resolvedOptions'); 1241 SetFunctionName(Intl.NumberFormat.prototype.resolvedOptions, 'resolvedOptions');
1211 %FunctionRemovePrototype(Intl.NumberFormat.prototype.resolvedOptions); 1242 %FunctionRemovePrototype(Intl.NumberFormat.prototype.resolvedOptions);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 return ''; 1350 return '';
1320 } 1351 }
1321 } 1352 }
1322 1353
1323 1354
1324 /** 1355 /**
1325 * Returns object that matches LDML representation of the date. 1356 * Returns object that matches LDML representation of the date.
1326 */ 1357 */
1327 function fromLDMLString(ldmlString) { 1358 function fromLDMLString(ldmlString) {
1328 // First remove '' quoted text, so we lose 'Uhr' strings. 1359 // First remove '' quoted text, so we lose 'Uhr' strings.
1329 ldmlString = ldmlString.replace(GetQuotedStringRE(), ''); 1360 ldmlString = %_CallFunction(ldmlString, GetQuotedStringRE(), '',
1361 StringReplace);
1330 1362
1331 var options = {}; 1363 var options = {};
1332 var match = ldmlString.match(/E{3,5}/g); 1364 var match = %_CallFunction(ldmlString, /E{3,5}/g, StringMatch);
1333 options = appendToDateTimeObject( 1365 options = appendToDateTimeObject(
1334 options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'}); 1366 options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'});
1335 1367
1336 match = ldmlString.match(/G{3,5}/g); 1368 match = %_CallFunction(ldmlString, /G{3,5}/g, StringMatch);
1337 options = appendToDateTimeObject( 1369 options = appendToDateTimeObject(
1338 options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'}); 1370 options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'});
1339 1371
1340 match = ldmlString.match(/y{1,2}/g); 1372 match = %_CallFunction(ldmlString, /y{1,2}/g, StringMatch);
1341 options = appendToDateTimeObject( 1373 options = appendToDateTimeObject(
1342 options, 'year', match, {y: 'numeric', yy: '2-digit'}); 1374 options, 'year', match, {y: 'numeric', yy: '2-digit'});
1343 1375
1344 match = ldmlString.match(/M{1,5}/g); 1376 match = %_CallFunction(ldmlString, /M{1,5}/g, StringMatch);
1345 options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit', 1377 options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit',
1346 M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'}); 1378 M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'});
1347 1379
1348 // Sometimes we get L instead of M for month - standalone name. 1380 // Sometimes we get L instead of M for month - standalone name.
1349 match = ldmlString.match(/L{1,5}/g); 1381 match = %_CallFunction(ldmlString, /L{1,5}/g, StringMatch);
1350 options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit', 1382 options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit',
1351 L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'}); 1383 L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'});
1352 1384
1353 match = ldmlString.match(/d{1,2}/g); 1385 match = %_CallFunction(ldmlString, /d{1,2}/g, StringMatch);
1354 options = appendToDateTimeObject( 1386 options = appendToDateTimeObject(
1355 options, 'day', match, {d: 'numeric', dd: '2-digit'}); 1387 options, 'day', match, {d: 'numeric', dd: '2-digit'});
1356 1388
1357 match = ldmlString.match(/h{1,2}/g); 1389 match = %_CallFunction(ldmlString, /h{1,2}/g, StringMatch);
1358 if (match !== null) { 1390 if (match !== null) {
1359 options['hour12'] = true; 1391 options['hour12'] = true;
1360 } 1392 }
1361 options = appendToDateTimeObject( 1393 options = appendToDateTimeObject(
1362 options, 'hour', match, {h: 'numeric', hh: '2-digit'}); 1394 options, 'hour', match, {h: 'numeric', hh: '2-digit'});
1363 1395
1364 match = ldmlString.match(/H{1,2}/g); 1396 match = %_CallFunction(ldmlString, /H{1,2}/g, StringMatch);
1365 if (match !== null) { 1397 if (match !== null) {
1366 options['hour12'] = false; 1398 options['hour12'] = false;
1367 } 1399 }
1368 options = appendToDateTimeObject( 1400 options = appendToDateTimeObject(
1369 options, 'hour', match, {H: 'numeric', HH: '2-digit'}); 1401 options, 'hour', match, {H: 'numeric', HH: '2-digit'});
1370 1402
1371 match = ldmlString.match(/m{1,2}/g); 1403 match = %_CallFunction(ldmlString, /m{1,2}/g, StringMatch);
1372 options = appendToDateTimeObject( 1404 options = appendToDateTimeObject(
1373 options, 'minute', match, {m: 'numeric', mm: '2-digit'}); 1405 options, 'minute', match, {m: 'numeric', mm: '2-digit'});
1374 1406
1375 match = ldmlString.match(/s{1,2}/g); 1407 match = %_CallFunction(ldmlString, /s{1,2}/g, StringMatch);
1376 options = appendToDateTimeObject( 1408 options = appendToDateTimeObject(
1377 options, 'second', match, {s: 'numeric', ss: '2-digit'}); 1409 options, 'second', match, {s: 'numeric', ss: '2-digit'});
1378 1410
1379 match = ldmlString.match(/z|zzzz/g); 1411 match = %_CallFunction(ldmlString, /z|zzzz/g, StringMatch);
1380 options = appendToDateTimeObject( 1412 options = appendToDateTimeObject(
1381 options, 'timeZoneName', match, {z: 'short', zzzz: 'long'}); 1413 options, 'timeZoneName', match, {z: 'short', zzzz: 'long'});
1382 1414
1383 return options; 1415 return options;
1384 } 1416 }
1385 1417
1386 1418
1387 function appendToDateTimeObject(options, option, match, pairs) { 1419 function appendToDateTimeObject(options, option, match, pairs) {
1388 if (IS_NULL(match)) { 1420 if (IS_NULL(match)) {
1389 if (!options.hasOwnProperty(option)) { 1421 if (!%HasOwnProperty(options, option)) {
1390 defineWEProperty(options, option, UNDEFINED); 1422 defineWEProperty(options, option, UNDEFINED);
1391 } 1423 }
1392 return options; 1424 return options;
1393 } 1425 }
1394 1426
1395 var property = match[0]; 1427 var property = match[0];
1396 defineWEProperty(options, option, pairs[property]); 1428 defineWEProperty(options, option, pairs[property]);
1397 1429
1398 return options; 1430 return options;
1399 } 1431 }
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
1654 1686
1655 1687
1656 /** 1688 /**
1657 * Returns a String value representing the result of calling ToNumber(date) 1689 * Returns a String value representing the result of calling ToNumber(date)
1658 * according to the effective locale and the formatting options of this 1690 * according to the effective locale and the formatting options of this
1659 * DateTimeFormat. 1691 * DateTimeFormat.
1660 */ 1692 */
1661 function formatDate(formatter, dateValue) { 1693 function formatDate(formatter, dateValue) {
1662 var dateMs; 1694 var dateMs;
1663 if (IS_UNDEFINED(dateValue)) { 1695 if (IS_UNDEFINED(dateValue)) {
1664 dateMs = GlobalDate.now(); 1696 dateMs = %DateCurrentTime();
1665 } else { 1697 } else {
1666 dateMs = $toNumber(dateValue); 1698 dateMs = $toNumber(dateValue);
1667 } 1699 }
1668 1700
1669 if (!IsFinite(dateMs)) throw MakeRangeError(kDateRange); 1701 if (!IsFinite(dateMs)) throw MakeRangeError(kDateRange);
1670 1702
1671 return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter), 1703 return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter),
1672 new GlobalDate(dateMs)); 1704 new GlobalDate(dateMs));
1673 } 1705 }
1674 1706
(...skipping 19 matching lines...) Expand all
1694 * Returns canonical Area/Location name, or throws an exception if the zone 1726 * Returns canonical Area/Location name, or throws an exception if the zone
1695 * name is invalid IANA name. 1727 * name is invalid IANA name.
1696 */ 1728 */
1697 function canonicalizeTimeZoneID(tzID) { 1729 function canonicalizeTimeZoneID(tzID) {
1698 // Skip undefined zones. 1730 // Skip undefined zones.
1699 if (IS_UNDEFINED(tzID)) { 1731 if (IS_UNDEFINED(tzID)) {
1700 return tzID; 1732 return tzID;
1701 } 1733 }
1702 1734
1703 // Special case handling (UTC, GMT). 1735 // Special case handling (UTC, GMT).
1704 var upperID = tzID.toUpperCase(); 1736 var upperID = %StringToUpperCase(tzID);
1705 if (upperID === 'UTC' || upperID === 'GMT' || 1737 if (upperID === 'UTC' || upperID === 'GMT' ||
1706 upperID === 'ETC/UTC' || upperID === 'ETC/GMT') { 1738 upperID === 'ETC/UTC' || upperID === 'ETC/GMT') {
1707 return 'UTC'; 1739 return 'UTC';
1708 } 1740 }
1709 1741
1710 // We expect only _ and / beside ASCII letters. 1742 // We expect only _ and / beside ASCII letters.
1711 // All inputs should conform to Area/Location from now on. 1743 // All inputs should conform to Area/Location from now on.
1712 var match = GetTimezoneNameCheckRE().exec(tzID); 1744 var match = %_CallFunction(tzID, GetTimezoneNameCheckRE(), StringMatch);
1713 if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID); 1745 if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID);
1714 1746
1715 var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]); 1747 var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]);
1716 var i = 3; 1748 var i = 3;
1717 while (!IS_UNDEFINED(match[i]) && i < match.length) { 1749 while (!IS_UNDEFINED(match[i]) && i < match.length) {
1718 result = result + '_' + toTitleCaseWord(match[i]); 1750 result = result + '_' + toTitleCaseWord(match[i]);
1719 i++; 1751 i++;
1720 } 1752 }
1721 1753
1722 return result; 1754 return result;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1961 if (%_IsConstructCall()) { 1993 if (%_IsConstructCall()) {
1962 throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); 1994 throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
1963 } 1995 }
1964 1996
1965 CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); 1997 CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize");
1966 1998
1967 var form = GlobalString(%_Arguments(0) || 'NFC'); 1999 var form = GlobalString(%_Arguments(0) || 'NFC');
1968 2000
1969 var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; 2001 var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD'];
1970 2002
1971 var normalizationForm = NORMALIZATION_FORMS.indexOf(form); 2003 var normalizationForm =
2004 %_CallFunction(NORMALIZATION_FORMS, form, ArrayIndexOf);
1972 if (normalizationForm === -1) { 2005 if (normalizationForm === -1) {
1973 throw MakeRangeError(kNormalizationForm, NORMALIZATION_FORMS.join(', ')); 2006 throw MakeRangeError(kNormalizationForm,
2007 %_CallFunction(NORMALIZATION_FORMS, ', ', ArrayJoin));
1974 } 2008 }
1975 2009
1976 return %StringNormalize(this, normalizationForm); 2010 return %StringNormalize(this, normalizationForm);
1977 } 2011 }
1978 ); 2012 );
1979 2013
1980 2014
1981 /** 2015 /**
1982 * Formats a Number object (this) using locale and options values. 2016 * Formats a Number object (this) using locale and options values.
1983 * If locale or options are omitted, defaults are used. 2017 * If locale or options are omitted, defaults are used.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2065 } 2099 }
2066 2100
2067 var locales = %_Arguments(0); 2101 var locales = %_Arguments(0);
2068 var options = %_Arguments(1); 2102 var options = %_Arguments(1);
2069 return toLocaleDateTime( 2103 return toLocaleDateTime(
2070 this, locales, options, 'time', 'time', 'dateformattime'); 2104 this, locales, options, 'time', 'time', 'dateformattime');
2071 } 2105 }
2072 ); 2106 );
2073 2107
2074 }) 2108 })
OLDNEW
« no previous file with comments | « src/array.js ('k') | src/regexp.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698