Chromium Code Reviews| Index: src/js/i18n.js |
| diff --git a/src/js/i18n.js b/src/js/i18n.js |
| index 6d38a3f2db194c5c1f262dbfa4d0b88599f3f7af..910f4e79784c71f6df939acf86ff18473749181b 100644 |
| --- a/src/js/i18n.js |
| +++ b/src/js/i18n.js |
| @@ -584,6 +584,13 @@ function freezeArray(input) { |
| return array; |
| } |
| +/* Make JS array[] out of InternalArray */ |
| +function makeArray(input) { |
| + var array = []; |
| + %MoveArrayContents(input, array); |
| + return array; |
| +} |
| + |
| /** |
| * It's sometimes desireable to leave user requested locale instead of ICU |
| @@ -718,6 +725,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 +743,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,18 +762,19 @@ 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) { |
| +function canonicalizeLocaleList(locales) { |
| var seen = new InternalArray(); |
| if (!IS_UNDEFINED(locales)) { |
| // We allow single string localeID. |
| if (typeof locales === 'string') { |
| %_Call(ArrayPush, seen, canonicalizeLanguageTag(locales)); |
| - return freezeArray(seen); |
| + return makeArray(seen); |
| } |
| var o = TO_OBJECT(locales); |
| - var len = TO_UINT32(o.length); |
| + var len = TO_LENGTH(o.length); |
| for (var k = 0; k < len; k++) { |
| if (k in o) { |
| @@ -777,20 +789,30 @@ function initializeLocaleList(locales) { |
| } |
| } |
| - return freezeArray(seen); |
| + return makeArray(seen); |
| } |
| +function initializeLocaleList(locales) { |
| + return freezeArray(canonicalizeLocaleList(locales)); |
|
Dan Ehrenberg
2016/08/12 18:59:19
This seems to make an extra copy of the array, whi
|
| +} |
| /** |
| - * 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 +907,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 canonicalizeLocaleList(locales); |
| + } |
| +); |
| + |
| /** |
| * Initializes the given object so it's a valid Collator instance. |
| * Useful for subclassing. |