OLD | NEW |
---|---|
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 ArrayIndexOf; | 20 var ArrayIndexOf; |
21 var ArrayJoin; | 21 var ArrayJoin; |
22 var ArrayPush; | 22 var ArrayPush; |
23 var InstallFunctions = utils.InstallFunctions; | |
24 var InstallGetter = utils.InstallGetter; | |
25 var IsFinite; | |
26 var IsNaN; | |
27 var GlobalBoolean = global.Boolean; | 23 var GlobalBoolean = global.Boolean; |
28 var GlobalDate = global.Date; | 24 var GlobalDate = global.Date; |
29 var GlobalNumber = global.Number; | 25 var GlobalNumber = global.Number; |
30 var GlobalRegExp = global.RegExp; | 26 var GlobalRegExp = global.RegExp; |
31 var GlobalString = global.String; | 27 var GlobalString = global.String; |
28 var InstallFunctions = utils.InstallFunctions; | |
29 var InstallGetter = utils.InstallGetter; | |
30 var InternalPackedArray = utils.InternalPackedArray; | |
31 var IsFinite; | |
32 var IsNaN; | |
32 var MakeError; | 33 var MakeError; |
33 var MakeRangeError; | 34 var MakeRangeError; |
34 var MakeTypeError; | 35 var MakeTypeError; |
35 var MathFloor; | 36 var MathFloor; |
36 var ObjectDefineProperties = utils.ImportNow("ObjectDefineProperties"); | 37 var ObjectDefineProperties = utils.ImportNow("ObjectDefineProperties"); |
37 var ObjectDefineProperty = utils.ImportNow("ObjectDefineProperty"); | 38 var ObjectDefineProperty = utils.ImportNow("ObjectDefineProperty"); |
38 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty"); | 39 var ObjectHasOwnProperty = utils.ImportNow("ObjectHasOwnProperty"); |
39 var patternSymbol = utils.ImportNow("intl_pattern_symbol"); | 40 var patternSymbol = utils.ImportNow("intl_pattern_symbol"); |
40 var RegExpTest; | |
41 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol"); | 41 var resolvedSymbol = utils.ImportNow("intl_resolved_symbol"); |
42 var SetFunctionName = utils.SetFunctionName; | 42 var SetFunctionName = utils.SetFunctionName; |
43 var RegExpMatch; | |
44 var RegExpReplace | |
43 var StringIndexOf; | 45 var StringIndexOf; |
44 var StringLastIndexOf; | 46 var StringLastIndexOf; |
45 var StringMatch; | |
46 var StringReplace; | |
47 var StringSplit; | 47 var StringSplit; |
48 var StringSubstr; | 48 var StringSubstr; |
49 var StringSubstring; | 49 var StringSubstring; |
50 | 50 |
51 utils.Import(function(from) { | 51 utils.Import(function(from) { |
52 ArrayIndexOf = from.ArrayIndexOf; | 52 ArrayIndexOf = from.ArrayIndexOf; |
53 ArrayJoin = from.ArrayJoin; | 53 ArrayJoin = from.ArrayJoin; |
54 ArrayPush = from.ArrayPush; | 54 ArrayPush = from.ArrayPush; |
55 IsFinite = from.IsFinite; | 55 IsFinite = from.IsFinite; |
56 IsNaN = from.IsNaN; | 56 IsNaN = from.IsNaN; |
57 MakeError = from.MakeError; | 57 MakeError = from.MakeError; |
58 MakeRangeError = from.MakeRangeError; | 58 MakeRangeError = from.MakeRangeError; |
59 MakeTypeError = from.MakeTypeError; | 59 MakeTypeError = from.MakeTypeError; |
60 MathFloor = from.MathFloor; | 60 MathFloor = from.MathFloor; |
61 RegExpTest = from.RegExpTest; | 61 RegExpMatch = from.InternalRegExpMatch; |
62 RegExpReplace = from.InternalRegExpReplace; | |
Dan Ehrenberg
2016/03/23 15:55:41
Could you use the original names, so it's clearer
Yang
2016/03/24 06:14:13
Done.
| |
62 StringIndexOf = from.StringIndexOf; | 63 StringIndexOf = from.StringIndexOf; |
63 StringLastIndexOf = from.StringLastIndexOf; | 64 StringLastIndexOf = from.StringLastIndexOf; |
64 StringMatch = from.StringMatch; | |
65 StringReplace = from.StringReplace; | |
66 StringSplit = from.StringSplit; | 65 StringSplit = from.StringSplit; |
67 StringSubstr = from.StringSubstr; | 66 StringSubstr = from.StringSubstr; |
68 StringSubstring = from.StringSubstring; | 67 StringSubstring = from.StringSubstring; |
69 }); | 68 }); |
70 | 69 |
71 // Utilities for definitions | 70 // Utilities for definitions |
72 | 71 |
73 function OverrideFunction(object, name, f) { | 72 function OverrideFunction(object, name, f) { |
74 %CheckIsBootstrapping(); | 73 %CheckIsBootstrapping(); |
75 ObjectDefineProperty(object, name, { value: f, | 74 ObjectDefineProperty(object, name, { value: f, |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 } | 267 } |
269 return TIMEZONE_NAME_LOCATION_PART_RE; | 268 return TIMEZONE_NAME_LOCATION_PART_RE; |
270 } | 269 } |
271 | 270 |
272 | 271 |
273 /** | 272 /** |
274 * Returns an intersection of locales and service supported locales. | 273 * Returns an intersection of locales and service supported locales. |
275 * Parameter locales is treated as a priority list. | 274 * Parameter locales is treated as a priority list. |
276 */ | 275 */ |
277 function supportedLocalesOf(service, locales, options) { | 276 function supportedLocalesOf(service, locales, options) { |
278 if (IS_NULL(%_Call(StringMatch, service, GetServiceRE()))) { | 277 if (IS_NULL(RegExpMatch(GetServiceRE(), service))) { |
279 throw MakeError(kWrongServiceType, service); | 278 throw MakeError(kWrongServiceType, service); |
280 } | 279 } |
281 | 280 |
282 // Provide defaults if matcher was not specified. | 281 // Provide defaults if matcher was not specified. |
283 if (IS_UNDEFINED(options)) { | 282 if (IS_UNDEFINED(options)) { |
284 options = {}; | 283 options = {}; |
285 } else { | 284 } else { |
286 options = TO_OBJECT(options); | 285 options = TO_OBJECT(options); |
287 } | 286 } |
288 | 287 |
(...skipping 27 matching lines...) Expand all Loading... | |
316 | 315 |
317 /** | 316 /** |
318 * Returns the subset of the provided BCP 47 language priority list for which | 317 * Returns the subset of the provided BCP 47 language priority list for which |
319 * this service has a matching locale when using the BCP 47 Lookup algorithm. | 318 * this service has a matching locale when using the BCP 47 Lookup algorithm. |
320 * Locales appear in the same order in the returned list as in the input list. | 319 * Locales appear in the same order in the returned list as in the input list. |
321 */ | 320 */ |
322 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { | 321 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { |
323 var matchedLocales = []; | 322 var matchedLocales = []; |
324 for (var i = 0; i < requestedLocales.length; ++i) { | 323 for (var i = 0; i < requestedLocales.length; ++i) { |
325 // Remove -u- extension. | 324 // Remove -u- extension. |
326 var locale = %_Call(StringReplace, | 325 var locale = RegExpReplace( |
327 requestedLocales[i], | 326 GetUnicodeExtensionRE(), requestedLocales[i], ''); |
328 GetUnicodeExtensionRE(), | |
329 ''); | |
330 do { | 327 do { |
331 if (!IS_UNDEFINED(availableLocales[locale])) { | 328 if (!IS_UNDEFINED(availableLocales[locale])) { |
332 // Push requested locale not the resolved one. | 329 // Push requested locale not the resolved one. |
333 %_Call(ArrayPush, matchedLocales, requestedLocales[i]); | 330 %_Call(ArrayPush, matchedLocales, requestedLocales[i]); |
334 break; | 331 break; |
335 } | 332 } |
336 // Truncate locale if possible, if not break. | 333 // Truncate locale if possible, if not break. |
337 var pos = %_Call(StringLastIndexOf, locale, '-'); | 334 var pos = %_Call(StringLastIndexOf, locale, '-'); |
338 if (pos === -1) { | 335 if (pos === -1) { |
339 break; | 336 break; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 | 422 |
426 return resolved; | 423 return resolved; |
427 } | 424 } |
428 | 425 |
429 | 426 |
430 /** | 427 /** |
431 * Returns best matched supported locale and extension info using basic | 428 * Returns best matched supported locale and extension info using basic |
432 * lookup algorithm. | 429 * lookup algorithm. |
433 */ | 430 */ |
434 function lookupMatcher(service, requestedLocales) { | 431 function lookupMatcher(service, requestedLocales) { |
435 if (IS_NULL(%_Call(StringMatch, service, GetServiceRE()))) { | 432 if (IS_NULL(RegExpMatch(GetServiceRE(), service))) { |
436 throw MakeError(kWrongServiceType, service); | 433 throw MakeError(kWrongServiceType, service); |
437 } | 434 } |
438 | 435 |
439 // Cache these, they don't ever change per service. | 436 // Cache these, they don't ever change per service. |
440 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) { | 437 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) { |
441 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); | 438 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); |
442 } | 439 } |
443 | 440 |
444 for (var i = 0; i < requestedLocales.length; ++i) { | 441 for (var i = 0; i < requestedLocales.length; ++i) { |
445 // Remove all extensions. | 442 // Remove all extensions. |
446 var locale = %_Call(StringReplace, requestedLocales[i], | 443 var locale = RegExpReplace(GetAnyExtensionRE(), requestedLocales[i], ''); |
447 GetAnyExtensionRE(), ''); | |
448 do { | 444 do { |
449 if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) { | 445 if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) { |
450 // Return the resolved locale and extension. | 446 // Return the resolved locale and extension. |
451 var extensionMatch = | 447 var extensionMatch = RegExpMatch( |
452 %_Call(StringMatch, requestedLocales[i], GetUnicodeExtensionRE()); | 448 GetUnicodeExtensionRE(), requestedLocales[i]); |
453 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; | 449 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; |
454 return {'locale': locale, 'extension': extension, 'position': i}; | 450 return {'locale': locale, 'extension': extension, 'position': i}; |
455 } | 451 } |
456 // Truncate locale if possible. | 452 // Truncate locale if possible. |
457 var pos = %_Call(StringLastIndexOf, locale, '-'); | 453 var pos = %_Call(StringLastIndexOf, locale, '-'); |
458 if (pos === -1) { | 454 if (pos === -1) { |
459 break; | 455 break; |
460 } | 456 } |
461 locale = %_Call(StringSubstring, locale, 0, pos); | 457 locale = %_Call(StringSubstring, locale, 0, pos); |
462 } while (true); | 458 } while (true); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 if (original === resolved) { | 612 if (original === resolved) { |
617 return original; | 613 return original; |
618 } | 614 } |
619 | 615 |
620 var locales = %GetLanguageTagVariants([original, resolved]); | 616 var locales = %GetLanguageTagVariants([original, resolved]); |
621 if (locales[0].maximized !== locales[1].maximized) { | 617 if (locales[0].maximized !== locales[1].maximized) { |
622 return resolved; | 618 return resolved; |
623 } | 619 } |
624 | 620 |
625 // Preserve extensions of resolved locale, but swap base tags with original. | 621 // Preserve extensions of resolved locale, but swap base tags with original. |
626 var resolvedBase = new GlobalRegExp('^' + locales[1].base); | 622 var resolvedBase = new GlobalRegExp('^' + locales[1].base, 'g'); |
627 return %_Call(StringReplace, resolved, resolvedBase, locales[0].base); | 623 return RegExpReplace(resolvedBase, resolved, locales[0].base); |
628 } | 624 } |
629 | 625 |
630 | 626 |
631 /** | 627 /** |
632 * Returns an Object that contains all of supported locales for a given | 628 * Returns an Object that contains all of supported locales for a given |
633 * service. | 629 * service. |
634 * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ | 630 * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ |
635 * that is supported. This is required by the spec. | 631 * that is supported. This is required by the spec. |
636 */ | 632 */ |
637 function getAvailableLocalesOf(service) { | 633 function getAvailableLocalesOf(service) { |
638 var available = %AvailableLocalesOf(service); | 634 var available = %AvailableLocalesOf(service); |
639 | 635 |
640 for (var i in available) { | 636 for (var i in available) { |
641 if (HAS_OWN_PROPERTY(available, i)) { | 637 if (HAS_OWN_PROPERTY(available, i)) { |
642 var parts = | 638 var parts = RegExpMatch(/^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/, i); |
643 %_Call(StringMatch, i, /^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/); | 639 if (!IS_NULL(parts)) { |
644 if (parts !== null) { | |
645 // Build xx-ZZ. We don't care about the actual value, | 640 // Build xx-ZZ. We don't care about the actual value, |
646 // as long it's not undefined. | 641 // as long it's not undefined. |
647 available[parts[1] + '-' + parts[3]] = null; | 642 available[parts[1] + '-' + parts[3]] = null; |
648 } | 643 } |
649 } | 644 } |
650 } | 645 } |
651 | 646 |
652 return available; | 647 return available; |
653 } | 648 } |
654 | 649 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
704 %StringToLowerCase(%_Call(StringSubstr, word, 1)); | 699 %StringToLowerCase(%_Call(StringSubstr, word, 1)); |
705 } | 700 } |
706 | 701 |
707 /** | 702 /** |
708 * Returns titlecased location, bueNos_airES -> Buenos_Aires | 703 * Returns titlecased location, bueNos_airES -> Buenos_Aires |
709 * or ho_cHi_minH -> Ho_Chi_Minh. It is locale-agnostic and only | 704 * or ho_cHi_minH -> Ho_Chi_Minh. It is locale-agnostic and only |
710 * deals with ASCII only characters. | 705 * deals with ASCII only characters. |
711 * 'of', 'au' and 'es' are special-cased and lowercased. | 706 * 'of', 'au' and 'es' are special-cased and lowercased. |
712 */ | 707 */ |
713 function toTitleCaseTimezoneLocation(location) { | 708 function toTitleCaseTimezoneLocation(location) { |
714 var match = %_Call(StringMatch, location, GetTimezoneNameLocationPartRE()); | 709 var match = RegExpMatch(GetTimezoneNameLocationPartRE(), location) |
715 if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, location); | 710 if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, location); |
716 | 711 |
717 var result = toTitleCaseWord(match[1]); | 712 var result = toTitleCaseWord(match[1]); |
718 if (!IS_UNDEFINED(match[2]) && 2 < match.length) { | 713 if (!IS_UNDEFINED(match[2]) && 2 < match.length) { |
719 // The first character is a separator, '_' or '-'. | 714 // The first character is a separator, '_' or '-'. |
720 // None of IANA zone names has both '_' and '-'. | 715 // None of IANA zone names has both '_' and '-'. |
721 var separator = %_Call(StringSubstring, match[2], 0, 1); | 716 var separator = %_Call(StringSubstring, match[2], 0, 1); |
722 var parts = %_Call(StringSplit, match[2], separator); | 717 var parts = %_Call(StringSplit, match[2], separator); |
723 for (var i = 1; i < parts.length; i++) { | 718 for (var i = 1; i < parts.length; i++) { |
724 var part = parts[i] | 719 var part = parts[i] |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
801 * Validates the language tag. Section 2.2.9 of the bcp47 spec | 796 * Validates the language tag. Section 2.2.9 of the bcp47 spec |
802 * defines a valid tag. | 797 * defines a valid tag. |
803 * | 798 * |
804 * ICU is too permissible and lets invalid tags, like | 799 * ICU is too permissible and lets invalid tags, like |
805 * hant-cmn-cn, through. | 800 * hant-cmn-cn, through. |
806 * | 801 * |
807 * Returns false if the language tag is invalid. | 802 * Returns false if the language tag is invalid. |
808 */ | 803 */ |
809 function isValidLanguageTag(locale) { | 804 function isValidLanguageTag(locale) { |
810 // Check if it's well-formed, including grandfadered tags. | 805 // Check if it's well-formed, including grandfadered tags. |
811 if (!%_Call(RegExpTest, GetLanguageTagRE(), locale)) { | 806 if (IS_NULL(RegExpMatch(GetLanguageTagRE(), locale))) { |
812 return false; | 807 return false; |
813 } | 808 } |
814 | 809 |
815 // Just return if it's a x- form. It's all private. | 810 // Just return if it's a x- form. It's all private. |
816 if (%_Call(StringIndexOf, locale, 'x-') === 0) { | 811 if (%_Call(StringIndexOf, locale, 'x-') === 0) { |
817 return true; | 812 return true; |
818 } | 813 } |
819 | 814 |
820 // Check if there are any duplicate variants or singletons (extensions). | 815 // Check if there are any duplicate variants or singletons (extensions). |
821 | 816 |
822 // Remove private use section. | 817 // Remove private use section. |
823 locale = %_Call(StringSplit, locale, /-x-/)[0]; | 818 locale = %_Call(StringSplit, locale, '-x-')[0]; |
824 | 819 |
825 // Skip language since it can match variant regex, so we start from 1. | 820 // Skip language since it can match variant regex, so we start from 1. |
826 // We are matching i-klingon here, but that's ok, since i-klingon-klingon | 821 // We are matching i-klingon here, but that's ok, since i-klingon-klingon |
827 // is not valid and would fail LANGUAGE_TAG_RE test. | 822 // is not valid and would fail LANGUAGE_TAG_RE test. |
828 var variants = []; | 823 var variants = []; |
829 var extensions = []; | 824 var extensions = []; |
830 var parts = %_Call(StringSplit, locale, /-/); | 825 var parts = %_Call(StringSplit, locale, '-'); |
831 for (var i = 1; i < parts.length; i++) { | 826 for (var i = 1; i < parts.length; i++) { |
832 var value = parts[i]; | 827 var value = parts[i]; |
833 if (%_Call(RegExpTest, GetLanguageVariantRE(), value) && | 828 if (!IS_NULL(RegExpMatch(GetLanguageVariantRE(), value)) && |
834 extensions.length === 0) { | 829 extensions.length === 0) { |
835 if (%_Call(ArrayIndexOf, variants, value) === -1) { | 830 if (%_Call(ArrayIndexOf, variants, value) === -1) { |
836 %_Call(ArrayPush, variants, value); | 831 %_Call(ArrayPush, variants, value); |
837 } else { | 832 } else { |
838 return false; | 833 return false; |
839 } | 834 } |
840 } | 835 } |
841 | 836 |
842 if (%_Call(RegExpTest, GetLanguageSingletonRE(), value)) { | 837 if (!IS_NULL(RegExpMatch(GetLanguageSingletonRE(), value))) { |
843 if (%_Call(ArrayIndexOf, extensions, value) === -1) { | 838 if (%_Call(ArrayIndexOf, extensions, value) === -1) { |
844 %_Call(ArrayPush, extensions, value); | 839 %_Call(ArrayPush, extensions, value); |
845 } else { | 840 } else { |
846 return false; | 841 return false; |
847 } | 842 } |
848 } | 843 } |
849 } | 844 } |
850 | 845 |
851 return true; | 846 return true; |
852 } | 847 } |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1088 | 1083 |
1089 | 1084 |
1090 AddBoundMethod(Intl.Collator, 'compare', compare, 2); | 1085 AddBoundMethod(Intl.Collator, 'compare', compare, 2); |
1091 | 1086 |
1092 /** | 1087 /** |
1093 * Verifies that the input is a well-formed ISO 4217 currency code. | 1088 * Verifies that the input is a well-formed ISO 4217 currency code. |
1094 * Don't uppercase to test. It could convert invalid code into a valid one. | 1089 * Don't uppercase to test. It could convert invalid code into a valid one. |
1095 * For example \u00DFP (Eszett+P) becomes SSP. | 1090 * For example \u00DFP (Eszett+P) becomes SSP. |
1096 */ | 1091 */ |
1097 function isWellFormedCurrencyCode(currency) { | 1092 function isWellFormedCurrencyCode(currency) { |
1098 return typeof currency == "string" && | 1093 return typeof currency == "string" && currency.length == 3 && |
1099 currency.length == 3 && | 1094 IS_NULL(RegExpMatch(/[^A-Za-z]/, currency)); |
1100 %_Call(StringMatch, currency, /[^A-Za-z]/) == null; | |
1101 } | 1095 } |
1102 | 1096 |
1103 | 1097 |
1104 /** | 1098 /** |
1105 * Returns the valid digit count for a property, or throws RangeError on | 1099 * Returns the valid digit count for a property, or throws RangeError on |
1106 * a value out of the range. | 1100 * a value out of the range. |
1107 */ | 1101 */ |
1108 function getNumberOption(options, property, min, max, fallback) { | 1102 function getNumberOption(options, property, min, max, fallback) { |
1109 var value = options[property]; | 1103 var value = options[property]; |
1110 if (!IS_UNDEFINED(value)) { | 1104 if (!IS_UNDEFINED(value)) { |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1420 return ''; | 1414 return ''; |
1421 } | 1415 } |
1422 } | 1416 } |
1423 | 1417 |
1424 | 1418 |
1425 /** | 1419 /** |
1426 * Returns object that matches LDML representation of the date. | 1420 * Returns object that matches LDML representation of the date. |
1427 */ | 1421 */ |
1428 function fromLDMLString(ldmlString) { | 1422 function fromLDMLString(ldmlString) { |
1429 // First remove '' quoted text, so we lose 'Uhr' strings. | 1423 // First remove '' quoted text, so we lose 'Uhr' strings. |
1430 ldmlString = %_Call(StringReplace, ldmlString, GetQuotedStringRE(), ''); | 1424 ldmlString = RegExpReplace(GetQuotedStringRE(), ldmlString, ''); |
1431 | 1425 |
1432 var options = {}; | 1426 var options = {}; |
1433 var match = %_Call(StringMatch, ldmlString, /E{3,5}/g); | 1427 var match = RegExpMatch(/E{3,5}/, ldmlString); |
1434 options = appendToDateTimeObject( | 1428 options = appendToDateTimeObject( |
1435 options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'}); | 1429 options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'}); |
1436 | 1430 |
1437 match = %_Call(StringMatch, ldmlString, /G{3,5}/g); | 1431 match = RegExpMatch(/G{3,5}/, ldmlString); |
1438 options = appendToDateTimeObject( | 1432 options = appendToDateTimeObject( |
1439 options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'}); | 1433 options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'}); |
1440 | 1434 |
1441 match = %_Call(StringMatch, ldmlString, /y{1,2}/g); | 1435 match = RegExpMatch(/y{1,2}/, ldmlString); |
1442 options = appendToDateTimeObject( | 1436 options = appendToDateTimeObject( |
1443 options, 'year', match, {y: 'numeric', yy: '2-digit'}); | 1437 options, 'year', match, {y: 'numeric', yy: '2-digit'}); |
1444 | 1438 |
1445 match = %_Call(StringMatch, ldmlString, /M{1,5}/g); | 1439 match = RegExpMatch(/M{1,5}/, ldmlString); |
1446 options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit', | 1440 options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit', |
1447 M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'}); | 1441 M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'}); |
1448 | 1442 |
1449 // Sometimes we get L instead of M for month - standalone name. | 1443 // Sometimes we get L instead of M for month - standalone name. |
1450 match = %_Call(StringMatch, ldmlString, /L{1,5}/g); | 1444 match = RegExpMatch(/L{1,5}/, ldmlString); |
1451 options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit', | 1445 options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit', |
1452 L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'}); | 1446 L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'}); |
1453 | 1447 |
1454 match = %_Call(StringMatch, ldmlString, /d{1,2}/g); | 1448 match = RegExpMatch(/d{1,2}/, ldmlString); |
1455 options = appendToDateTimeObject( | 1449 options = appendToDateTimeObject( |
1456 options, 'day', match, {d: 'numeric', dd: '2-digit'}); | 1450 options, 'day', match, {d: 'numeric', dd: '2-digit'}); |
1457 | 1451 |
1458 match = %_Call(StringMatch, ldmlString, /h{1,2}/g); | 1452 match = RegExpMatch(/h{1,2}/, ldmlString); |
1459 if (match !== null) { | 1453 if (match !== null) { |
1460 options['hour12'] = true; | 1454 options['hour12'] = true; |
1461 } | 1455 } |
1462 options = appendToDateTimeObject( | 1456 options = appendToDateTimeObject( |
1463 options, 'hour', match, {h: 'numeric', hh: '2-digit'}); | 1457 options, 'hour', match, {h: 'numeric', hh: '2-digit'}); |
1464 | 1458 |
1465 match = %_Call(StringMatch, ldmlString, /H{1,2}/g); | 1459 match = RegExpMatch(/H{1,2}/, ldmlString); |
1466 if (match !== null) { | 1460 if (match !== null) { |
1467 options['hour12'] = false; | 1461 options['hour12'] = false; |
1468 } | 1462 } |
1469 options = appendToDateTimeObject( | 1463 options = appendToDateTimeObject( |
1470 options, 'hour', match, {H: 'numeric', HH: '2-digit'}); | 1464 options, 'hour', match, {H: 'numeric', HH: '2-digit'}); |
1471 | 1465 |
1472 match = %_Call(StringMatch, ldmlString, /m{1,2}/g); | 1466 match = RegExpMatch(/m{1,2}/, ldmlString); |
1473 options = appendToDateTimeObject( | 1467 options = appendToDateTimeObject( |
1474 options, 'minute', match, {m: 'numeric', mm: '2-digit'}); | 1468 options, 'minute', match, {m: 'numeric', mm: '2-digit'}); |
1475 | 1469 |
1476 match = %_Call(StringMatch, ldmlString, /s{1,2}/g); | 1470 match = RegExpMatch(/s{1,2}/, ldmlString); |
1477 options = appendToDateTimeObject( | 1471 options = appendToDateTimeObject( |
1478 options, 'second', match, {s: 'numeric', ss: '2-digit'}); | 1472 options, 'second', match, {s: 'numeric', ss: '2-digit'}); |
1479 | 1473 |
1480 match = %_Call(StringMatch, ldmlString, /z|zzzz/g); | 1474 match = RegExpMatch(/z|zzzz/, ldmlString); |
1481 options = appendToDateTimeObject( | 1475 options = appendToDateTimeObject( |
1482 options, 'timeZoneName', match, {z: 'short', zzzz: 'long'}); | 1476 options, 'timeZoneName', match, {z: 'short', zzzz: 'long'}); |
1483 | 1477 |
1484 return options; | 1478 return options; |
1485 } | 1479 } |
1486 | 1480 |
1487 | 1481 |
1488 function appendToDateTimeObject(options, option, match, pairs) { | 1482 function appendToDateTimeObject(options, option, match, pairs) { |
1489 if (IS_NULL(match)) { | 1483 if (IS_NULL(match)) { |
1490 if (!HAS_OWN_PROPERTY(options, option)) { | 1484 if (!HAS_OWN_PROPERTY(options, option)) { |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1797 var upperID = %StringToUpperCase(tzID); | 1791 var upperID = %StringToUpperCase(tzID); |
1798 if (upperID === 'UTC' || upperID === 'GMT' || | 1792 if (upperID === 'UTC' || upperID === 'GMT' || |
1799 upperID === 'ETC/UTC' || upperID === 'ETC/GMT') { | 1793 upperID === 'ETC/UTC' || upperID === 'ETC/GMT') { |
1800 return 'UTC'; | 1794 return 'UTC'; |
1801 } | 1795 } |
1802 | 1796 |
1803 // TODO(jshin): Add support for Etc/GMT[+-]([1-9]|1[0-2]) | 1797 // TODO(jshin): Add support for Etc/GMT[+-]([1-9]|1[0-2]) |
1804 | 1798 |
1805 // We expect only _, '-' and / beside ASCII letters. | 1799 // We expect only _, '-' and / beside ASCII letters. |
1806 // All inputs should conform to Area/Location(/Location)* from now on. | 1800 // All inputs should conform to Area/Location(/Location)* from now on. |
1807 var match = %_Call(StringMatch, tzID, GetTimezoneNameCheckRE()); | 1801 var match = RegExpMatch(GetTimezoneNameCheckRE(), tzID); |
1808 if (IS_NULL(match)) throw MakeRangeError(kExpectedTimezoneID, tzID); | 1802 if (IS_NULL(match)) throw MakeRangeError(kExpectedTimezoneID, tzID); |
1809 | 1803 |
1810 var result = toTitleCaseTimezoneLocation(match[1]) + '/' + | 1804 var result = toTitleCaseTimezoneLocation(match[1]) + '/' + |
1811 toTitleCaseTimezoneLocation(match[2]); | 1805 toTitleCaseTimezoneLocation(match[2]); |
1812 | 1806 |
1813 if (!IS_UNDEFINED(match[3]) && 3 < match.length) { | 1807 if (!IS_UNDEFINED(match[3]) && 3 < match.length) { |
1814 var locations = %_Call(StringSplit, match[3], '/'); | 1808 var locations = %_Call(StringSplit, match[3], '/'); |
1815 // The 1st element is empty. Starts with i=1. | 1809 // The 1st element is empty. Starts with i=1. |
1816 for (var i = 1; i < locations.length; i++) { | 1810 for (var i = 1; i < locations.length; i++) { |
1817 result = result + '/' + toTitleCaseTimezoneLocation(locations[i]); | 1811 result = result + '/' + toTitleCaseTimezoneLocation(locations[i]); |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2148 } | 2142 } |
2149 | 2143 |
2150 var locales = arguments[0]; | 2144 var locales = arguments[0]; |
2151 var options = arguments[1]; | 2145 var options = arguments[1]; |
2152 return toLocaleDateTime( | 2146 return toLocaleDateTime( |
2153 this, locales, options, 'time', 'time', 'dateformattime'); | 2147 this, locales, options, 'time', 'time', 'dateformattime'); |
2154 } | 2148 } |
2155 ); | 2149 ); |
2156 | 2150 |
2157 }) | 2151 }) |
OLD | NEW |