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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 }; | 146 }; |
147 | 147 |
148 /** | 148 /** |
149 * Caches default ICU locale. | 149 * Caches default ICU locale. |
150 */ | 150 */ |
151 var DEFAULT_ICU_LOCALE = UNDEFINED; | 151 var DEFAULT_ICU_LOCALE = UNDEFINED; |
152 | 152 |
153 function GetDefaultICULocaleJS() { | 153 function GetDefaultICULocaleJS() { |
154 if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) { | 154 if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) { |
155 DEFAULT_ICU_LOCALE = %GetDefaultICULocale(); | 155 DEFAULT_ICU_LOCALE = %GetDefaultICULocale(); |
156 // Check that this is a valid default, otherwise fall back to "en" | |
157 for (let service in AVAILABLE_LOCALES) { | |
158 if (IS_UNDEFINED(getAvailableLocalesOf(service)[DEFAULT_ICU_LOCALE])) { | |
159 DEFAULT_ICU_LOCALE = "en"; | |
jungshik at Google
2017/01/19 19:16:22
Hmm... I'm not sure of falling back to 'en'. How a
Dan Ehrenberg
2017/02/10 08:54:28
Done.
| |
160 break; | |
161 } | |
162 } | |
156 } | 163 } |
157 return DEFAULT_ICU_LOCALE; | 164 return DEFAULT_ICU_LOCALE; |
158 } | 165 } |
159 | 166 |
160 /** | 167 /** |
161 * Unicode extension regular expression. | 168 * Unicode extension regular expression. |
162 */ | 169 */ |
163 var UNICODE_EXTENSION_RE = UNDEFINED; | 170 var UNICODE_EXTENSION_RE = UNDEFINED; |
164 | 171 |
165 function GetUnicodeExtensionRE() { | 172 function GetUnicodeExtensionRE() { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 matcher = TO_STRING(matcher); | 298 matcher = TO_STRING(matcher); |
292 if (matcher !== 'lookup' && matcher !== 'best fit') { | 299 if (matcher !== 'lookup' && matcher !== 'best fit') { |
293 throw %make_range_error(kLocaleMatcher, matcher); | 300 throw %make_range_error(kLocaleMatcher, matcher); |
294 } | 301 } |
295 } else { | 302 } else { |
296 matcher = 'best fit'; | 303 matcher = 'best fit'; |
297 } | 304 } |
298 | 305 |
299 var requestedLocales = initializeLocaleList(locales); | 306 var requestedLocales = initializeLocaleList(locales); |
300 | 307 |
301 // Cache these, they don't ever change per service. | 308 var availableLocales = getAvailableLocalesOf(service); |
302 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) { | |
303 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); | |
304 } | |
305 | 309 |
306 // Use either best fit or lookup algorithm to match locales. | 310 // Use either best fit or lookup algorithm to match locales. |
307 if (matcher === 'best fit') { | 311 if (matcher === 'best fit') { |
308 return initializeLocaleList(bestFitSupportedLocalesOf( | 312 return initializeLocaleList(bestFitSupportedLocalesOf( |
309 requestedLocales, AVAILABLE_LOCALES[service])); | 313 requestedLocales, availableLocales)); |
310 } | 314 } |
311 | 315 |
312 return initializeLocaleList(lookupSupportedLocalesOf( | 316 return initializeLocaleList(lookupSupportedLocalesOf( |
313 requestedLocales, AVAILABLE_LOCALES[service])); | 317 requestedLocales, availableLocales)); |
314 } | 318 } |
315 | 319 |
316 | 320 |
317 /** | 321 /** |
318 * Returns the subset of the provided BCP 47 language priority list for which | 322 * 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. | 323 * 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. | 324 * Locales appear in the same order in the returned list as in the input list. |
321 */ | 325 */ |
322 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { | 326 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { |
323 var matchedLocales = new InternalArray(); | 327 var matchedLocales = new InternalArray(); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 | 434 |
431 /** | 435 /** |
432 * Returns best matched supported locale and extension info using basic | 436 * Returns best matched supported locale and extension info using basic |
433 * lookup algorithm. | 437 * lookup algorithm. |
434 */ | 438 */ |
435 function lookupMatcher(service, requestedLocales) { | 439 function lookupMatcher(service, requestedLocales) { |
436 if (IS_NULL(%regexp_internal_match(GetServiceRE(), service))) { | 440 if (IS_NULL(%regexp_internal_match(GetServiceRE(), service))) { |
437 throw %make_error(kWrongServiceType, service); | 441 throw %make_error(kWrongServiceType, service); |
438 } | 442 } |
439 | 443 |
440 // Cache these, they don't ever change per service. | 444 var availableLocales = getAvailableLocalesOf(service); |
441 if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) { | |
442 AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); | |
443 } | |
444 | 445 |
445 for (var i = 0; i < requestedLocales.length; ++i) { | 446 for (var i = 0; i < requestedLocales.length; ++i) { |
446 // Remove all extensions. | 447 // Remove all extensions. |
447 var locale = %RegExpInternalReplace( | 448 var locale = %RegExpInternalReplace( |
448 GetAnyExtensionRE(), requestedLocales[i], ''); | 449 GetAnyExtensionRE(), requestedLocales[i], ''); |
449 do { | 450 do { |
450 if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) { | 451 if (!IS_UNDEFINED(availableLocales[locale])) { |
451 // Return the resolved locale and extension. | 452 // Return the resolved locale and extension. |
452 var extensionMatch = %regexp_internal_match( | 453 var extensionMatch = %regexp_internal_match( |
453 GetUnicodeExtensionRE(), requestedLocales[i]); | 454 GetUnicodeExtensionRE(), requestedLocales[i]); |
454 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; | 455 var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; |
455 return {'locale': locale, 'extension': extension, 'position': i}; | 456 return {'locale': locale, 'extension': extension, 'position': i}; |
456 } | 457 } |
457 // Truncate locale if possible. | 458 // Truncate locale if possible. |
458 var pos = %StringLastIndexOf(locale, '-'); | 459 var pos = %StringLastIndexOf(locale, '-'); |
459 if (pos === -1) { | 460 if (pos === -1) { |
460 break; | 461 break; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
651 } | 652 } |
652 | 653 |
653 | 654 |
654 /** | 655 /** |
655 * Returns an Object that contains all of supported locales for a given | 656 * Returns an Object that contains all of supported locales for a given |
656 * service. | 657 * service. |
657 * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ | 658 * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ |
658 * that is supported. This is required by the spec. | 659 * that is supported. This is required by the spec. |
659 */ | 660 */ |
660 function getAvailableLocalesOf(service) { | 661 function getAvailableLocalesOf(service) { |
662 // Cache these, they don't ever change per service. | |
663 if (!IS_UNDEFINED(AVAILABLE_LOCALES[service])) { | |
664 return AVAILABLE_LOCALES[service]; | |
665 } | |
666 | |
661 var available = %AvailableLocalesOf(service); | 667 var available = %AvailableLocalesOf(service); |
662 | 668 |
663 for (var i in available) { | 669 for (var i in available) { |
664 if (HAS_OWN_PROPERTY(available, i)) { | 670 if (HAS_OWN_PROPERTY(available, i)) { |
665 var parts = %regexp_internal_match( | 671 var parts = %regexp_internal_match( |
666 /^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/, i); | 672 /^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/, i); |
667 if (!IS_NULL(parts)) { | 673 if (!IS_NULL(parts)) { |
668 // Build xx-ZZ. We don't care about the actual value, | 674 // Build xx-ZZ. We don't care about the actual value, |
669 // as long it's not undefined. | 675 // as long it's not undefined. |
670 available[parts[1] + '-' + parts[3]] = null; | 676 available[parts[1] + '-' + parts[3]] = null; |
671 } | 677 } |
672 } | 678 } |
673 } | 679 } |
674 | 680 |
681 AVAILABLE_LOCALES[service] = available; | |
682 | |
675 return available; | 683 return available; |
676 } | 684 } |
677 | 685 |
678 | 686 |
679 /** | 687 /** |
680 * Defines a property and sets writable and enumerable to true. | 688 * Defines a property and sets writable and enumerable to true. |
681 * Configurable is false by default. | 689 * Configurable is false by default. |
682 */ | 690 */ |
683 function defineWEProperty(object, property, value) { | 691 function defineWEProperty(object, property, value) { |
684 %object_define_property(object, property, | 692 %object_define_property(object, property, |
(...skipping 1481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2166 } | 2174 } |
2167 ); | 2175 ); |
2168 | 2176 |
2169 %FunctionRemovePrototype(FormatDateToParts); | 2177 %FunctionRemovePrototype(FormatDateToParts); |
2170 | 2178 |
2171 utils.Export(function(to) { | 2179 utils.Export(function(to) { |
2172 to.FormatDateToParts = FormatDateToParts; | 2180 to.FormatDateToParts = FormatDateToParts; |
2173 }); | 2181 }); |
2174 | 2182 |
2175 }) | 2183 }) |
OLD | NEW |