| Index: src/js/i18n.js
|
| diff --git a/src/js/i18n.js b/src/js/i18n.js
|
| index 6d38a3f2db194c5c1f262dbfa4d0b88599f3f7af..27fb746bb0f4ef67ff63c5a5f92c3dda5596a8d1 100644
|
| --- a/src/js/i18n.js
|
| +++ b/src/js/i18n.js
|
| @@ -718,6 +718,7 @@ function toTitleCaseTimezoneLocation(location) {
|
|
|
| /**
|
| * Canonicalizes the language tag, or throws in case the tag is invalid.
|
| + * ECMA 402 9.2.1 steps 7.c ii ~ v.
|
| */
|
| function canonicalizeLanguageTag(localeID) {
|
| // null is typeof 'object' so we have to do extra check.
|
| @@ -735,11 +736,14 @@ function canonicalizeLanguageTag(localeID) {
|
|
|
| var localeString = TO_STRING(localeID);
|
|
|
| - if (isValidLanguageTag(localeString) === false) {
|
| + if (isStructuallyValidLanguageTag(localeString) === false) {
|
| throw %make_range_error(kInvalidLanguageTag, localeString);
|
| }
|
|
|
| + // ECMA 402 6.2.3
|
| var tag = %CanonicalizeLanguageTag(localeString);
|
| + // TODO(jshin): This should not happen because the structual validity
|
| + // is already checked. If that's the case, remove this.
|
| if (tag === 'invalid-tag') {
|
| throw %make_range_error(kInvalidLanguageTag, localeString);
|
| }
|
| @@ -751,6 +755,7 @@ function canonicalizeLanguageTag(localeID) {
|
| /**
|
| * Returns an array where all locales are canonicalized and duplicates removed.
|
| * Throws on locales that are not well formed BCP47 tags.
|
| + * ECMA 402 8.2.1 steps 1 (ECMA 402 9.2.1) and 2.
|
| */
|
| function initializeLocaleList(locales) {
|
| var seen = new InternalArray();
|
| @@ -762,9 +767,11 @@ function initializeLocaleList(locales) {
|
| }
|
|
|
| var o = TO_OBJECT(locales);
|
| - var len = TO_UINT32(o.length);
|
| + var len = TO_LENGTH(o.length);
|
|
|
| for (var k = 0; k < len; k++) {
|
| + // ECMA 402 9.2.1 step 7a converts 'k' to String. Does it make
|
| + // any difference?
|
| if (k in o) {
|
| var value = o[k];
|
|
|
| @@ -782,15 +789,22 @@ function initializeLocaleList(locales) {
|
|
|
|
|
| /**
|
| - * Validates the language tag. Section 2.2.9 of the bcp47 spec
|
| - * defines a valid tag.
|
| + * Check the structual Validity of the language tag per ECMA 402 6.2.2:
|
| + * - Well-formed per RFC 5646 2.1
|
| + * - There are no duplicate variant subtags
|
| + * - There are no duplicate singletion (extension) subtags
|
| + *
|
| + * One extra-check is done (from RFC 5646 2.2.9): the tag is compared
|
| + * against the list of grandfathered tags. However, subtags for
|
| + * primary/extended language, script, region, variant are not checked
|
| + * against the IANA language subtag registry.
|
| *
|
| * ICU is too permissible and lets invalid tags, like
|
| * hant-cmn-cn, through.
|
| *
|
| * Returns false if the language tag is invalid.
|
| */
|
| -function isValidLanguageTag(locale) {
|
| +function isStructuallyValidLanguageTag(locale) {
|
| // Check if it's well-formed, including grandfadered tags.
|
| if (IS_NULL(InternalRegExpMatch(GetLanguageTagRE(), locale))) {
|
| return false;
|
| @@ -885,6 +899,16 @@ var resolvedAccessor = {
|
| }
|
| };
|
|
|
| +// ECMA 402 section 8.2.1
|
| +InstallFunction(Intl, 'getCanonicalLocales', function(locales) {
|
| + if (!IS_UNDEFINED(new.target)) {
|
| + throw %make_type_error(kOrdinaryFunctionCalledAsConstructor);
|
| + }
|
| +
|
| + return initializeLocaleList(locales);
|
| + }
|
| +);
|
| +
|
| /**
|
| * Initializes the given object so it's a valid Collator instance.
|
| * Useful for subclassing.
|
|
|