| 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 */ |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 ((lowercasedPart !== 'es' && | 711 ((lowercasedPart !== 'es' && |
| 712 lowercasedPart !== 'of' && lowercasedPart !== 'au') ? | 712 lowercasedPart !== 'of' && lowercasedPart !== 'au') ? |
| 713 toTitleCaseWord(part) : lowercasedPart); | 713 toTitleCaseWord(part) : lowercasedPart); |
| 714 } | 714 } |
| 715 } | 715 } |
| 716 return result; | 716 return result; |
| 717 } | 717 } |
| 718 | 718 |
| 719 /** | 719 /** |
| 720 * Canonicalizes the language tag, or throws in case the tag is invalid. | 720 * Canonicalizes the language tag, or throws in case the tag is invalid. |
| 721 * ECMA 402 9.2.1 steps 7.c ii ~ v. | |
| 722 */ | 721 */ |
| 723 function canonicalizeLanguageTag(localeID) { | 722 function canonicalizeLanguageTag(localeID) { |
| 724 // null is typeof 'object' so we have to do extra check. | 723 // null is typeof 'object' so we have to do extra check. |
| 725 if ((!IS_STRING(localeID) && !IS_RECEIVER(localeID)) || | 724 if ((!IS_STRING(localeID) && !IS_RECEIVER(localeID)) || |
| 726 IS_NULL(localeID)) { | 725 IS_NULL(localeID)) { |
| 727 throw %make_type_error(kLanguageID); | 726 throw %make_type_error(kLanguageID); |
| 728 } | 727 } |
| 729 | 728 |
| 730 // Optimize for the most common case; a language code alone in | 729 // Optimize for the most common case; a language code alone in |
| 731 // the canonical form/lowercase (e.g. "en", "fil"). | 730 // the canonical form/lowercase (e.g. "en", "fil"). |
| 732 if (IS_STRING(localeID) && | 731 if (IS_STRING(localeID) && |
| 733 !IS_NULL(InternalRegExpMatch(/^[a-z]{2,3}$/, localeID))) { | 732 !IS_NULL(InternalRegExpMatch(/^[a-z]{2,3}$/, localeID))) { |
| 734 return localeID; | 733 return localeID; |
| 735 } | 734 } |
| 736 | 735 |
| 737 var localeString = TO_STRING(localeID); | 736 var localeString = TO_STRING(localeID); |
| 738 | 737 |
| 739 if (isStructuallyValidLanguageTag(localeString) === false) { | 738 if (isValidLanguageTag(localeString) === false) { |
| 740 throw %make_range_error(kInvalidLanguageTag, localeString); | 739 throw %make_range_error(kInvalidLanguageTag, localeString); |
| 741 } | 740 } |
| 742 | 741 |
| 743 // ECMA 402 6.2.3 | |
| 744 var tag = %CanonicalizeLanguageTag(localeString); | 742 var tag = %CanonicalizeLanguageTag(localeString); |
| 745 // TODO(jshin): This should not happen because the structual validity | |
| 746 // is already checked. If that's the case, remove this. | |
| 747 if (tag === 'invalid-tag') { | 743 if (tag === 'invalid-tag') { |
| 748 throw %make_range_error(kInvalidLanguageTag, localeString); | 744 throw %make_range_error(kInvalidLanguageTag, localeString); |
| 749 } | 745 } |
| 750 | 746 |
| 751 return tag; | 747 return tag; |
| 752 } | 748 } |
| 753 | 749 |
| 754 | 750 |
| 755 /** | 751 /** |
| 756 * Returns an array where all locales are canonicalized and duplicates removed. | 752 * Returns an array where all locales are canonicalized and duplicates removed. |
| 757 * Throws on locales that are not well formed BCP47 tags. | 753 * Throws on locales that are not well formed BCP47 tags. |
| 758 * ECMA 402 8.2.1 steps 1 and 2. | |
| 759 */ | 754 */ |
| 760 function initializeLocaleList(locales) { | 755 function initializeLocaleList(locales) { |
| 761 var seen = new InternalArray(); | 756 var seen = new InternalArray(); |
| 762 if (!IS_UNDEFINED(locales)) { | 757 if (!IS_UNDEFINED(locales)) { |
| 763 // We allow single string localeID. | 758 // We allow single string localeID. |
| 764 if (typeof locales === 'string') { | 759 if (typeof locales === 'string') { |
| 765 %_Call(ArrayPush, seen, canonicalizeLanguageTag(locales)); | 760 %_Call(ArrayPush, seen, canonicalizeLanguageTag(locales)); |
| 766 return freezeArray(seen); | 761 return freezeArray(seen); |
| 767 } | 762 } |
| 768 | 763 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 780 } | 775 } |
| 781 } | 776 } |
| 782 } | 777 } |
| 783 } | 778 } |
| 784 | 779 |
| 785 return freezeArray(seen); | 780 return freezeArray(seen); |
| 786 } | 781 } |
| 787 | 782 |
| 788 | 783 |
| 789 /** | 784 /** |
| 790 * Check the structual Validity of the language tag per ECMA 402 6.2.2: | 785 * Validates the language tag. Section 2.2.9 of the bcp47 spec |
| 791 * - Well-formed per RFC 5646 2.1 | 786 * defines a valid tag. |
| 792 * - There are no duplicate variant subtags | |
| 793 * - There are no duplicate singletion (extension) subtags | |
| 794 * | |
| 795 * One extra-check is done (from RFC 5646 2.2.9): the tag is compared | |
| 796 * against the list of grandfathered tags. However, subtags for | |
| 797 * primary/extended language, script, region, variant are not checked | |
| 798 * against the IANA language subtag registry. | |
| 799 * | 787 * |
| 800 * ICU is too permissible and lets invalid tags, like | 788 * ICU is too permissible and lets invalid tags, like |
| 801 * hant-cmn-cn, through. | 789 * hant-cmn-cn, through. |
| 802 * | 790 * |
| 803 * Returns false if the language tag is invalid. | 791 * Returns false if the language tag is invalid. |
| 804 */ | 792 */ |
| 805 function isStructuallyValidLanguageTag(locale) { | 793 function isValidLanguageTag(locale) { |
| 806 // Check if it's well-formed, including grandfadered tags. | 794 // Check if it's well-formed, including grandfadered tags. |
| 807 if (IS_NULL(InternalRegExpMatch(GetLanguageTagRE(), locale))) { | 795 if (IS_NULL(InternalRegExpMatch(GetLanguageTagRE(), locale))) { |
| 808 return false; | 796 return false; |
| 809 } | 797 } |
| 810 | 798 |
| 811 // Just return if it's a x- form. It's all private. | 799 // Just return if it's a x- form. It's all private. |
| 812 if (%_Call(StringIndexOf, locale, 'x-') === 0) { | 800 if (%_Call(StringIndexOf, locale, 'x-') === 0) { |
| 813 return true; | 801 return true; |
| 814 } | 802 } |
| 815 | 803 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 var resolvedAccessor = { | 878 var resolvedAccessor = { |
| 891 get() { | 879 get() { |
| 892 %IncrementUseCounter(kIntlResolved); | 880 %IncrementUseCounter(kIntlResolved); |
| 893 return this[resolvedSymbol]; | 881 return this[resolvedSymbol]; |
| 894 }, | 882 }, |
| 895 set(value) { | 883 set(value) { |
| 896 this[resolvedSymbol] = value; | 884 this[resolvedSymbol] = value; |
| 897 } | 885 } |
| 898 }; | 886 }; |
| 899 | 887 |
| 900 // ECMA 402 section 8.2.1 | |
| 901 InstallFunction(Intl, 'getCanonicalLocales', function(locales) { | |
| 902 if (!IS_UNDEFINED(new.target)) { | |
| 903 throw %make_type_error(kOrdinaryFunctionCalledAsConstructor); | |
| 904 } | |
| 905 | |
| 906 return initializeLocaleList(locales); | |
| 907 } | |
| 908 ); | |
| 909 | |
| 910 /** | 888 /** |
| 911 * Initializes the given object so it's a valid Collator instance. | 889 * Initializes the given object so it's a valid Collator instance. |
| 912 * Useful for subclassing. | 890 * Useful for subclassing. |
| 913 */ | 891 */ |
| 914 function initializeCollator(collator, locales, options) { | 892 function initializeCollator(collator, locales, options) { |
| 915 if (%IsInitializedIntlObject(collator)) { | 893 if (%IsInitializedIntlObject(collator)) { |
| 916 throw %make_type_error(kReinitializeIntl, "Collator"); | 894 throw %make_type_error(kReinitializeIntl, "Collator"); |
| 917 } | 895 } |
| 918 | 896 |
| 919 if (IS_UNDEFINED(options)) { | 897 if (IS_UNDEFINED(options)) { |
| (...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2268 } | 2246 } |
| 2269 ); | 2247 ); |
| 2270 | 2248 |
| 2271 utils.Export(function(to) { | 2249 utils.Export(function(to) { |
| 2272 to.AddBoundMethod = AddBoundMethod; | 2250 to.AddBoundMethod = AddBoundMethod; |
| 2273 to.IntlParseDate = IntlParseDate; | 2251 to.IntlParseDate = IntlParseDate; |
| 2274 to.IntlParseNumber = IntlParseNumber; | 2252 to.IntlParseNumber = IntlParseNumber; |
| 2275 }); | 2253 }); |
| 2276 | 2254 |
| 2277 }) | 2255 }) |
| OLD | NEW |