@@ -152,18 +152,11 @@ var AVAILABLE_LOCALES = {
152152 */
153153var DEFAULT_ICU_LOCALE = UNDEFINED ;
154154
155- function GetDefaultICULocaleJS ( service ) {
155+ function GetDefaultICULocaleJS ( ) {
156156 if ( IS_UNDEFINED ( DEFAULT_ICU_LOCALE ) ) {
157157 DEFAULT_ICU_LOCALE = % GetDefaultICULocale ( ) ;
158158 }
159- // Check that this is a valid default for this service,
160- // otherwise fall back to "und"
161- // TODO(littledan,jshin): AvailableLocalesOf sometimes excludes locales
162- // which don't require tailoring, but work fine with root data. Look into
163- // exposing this fact in ICU or the way Chrome bundles data.
164- return ( IS_UNDEFINED ( service ) ||
165- HAS_OWN_PROPERTY ( getAvailableLocalesOf ( service ) , DEFAULT_ICU_LOCALE ) )
166- ? DEFAULT_ICU_LOCALE : "und" ;
159+ return DEFAULT_ICU_LOCALE ;
167160}
168161
169162/**
@@ -434,6 +427,48 @@ function resolveLocale(service, requestedLocales, options) {
434427}
435428
436429
430+ /**
431+ * Look up the longest non-empty prefix of |locale| that is an element of
432+ * |availableLocales|. Returns undefined when the |locale| is completely
433+ * unsupported by |availableLocales|.
434+ */
435+ function bestAvailableLocale ( availableLocales , locale ) {
436+ do {
437+ if ( ! IS_UNDEFINED ( availableLocales [ locale ] ) ) {
438+ return locale ;
439+ }
440+ // Truncate locale if possible.
441+ var pos = % StringLastIndexOf ( locale , '-' ) ;
442+ if ( pos === - 1 ) {
443+ break ;
444+ }
445+ locale = % _Call ( StringSubstring , locale , 0 , pos ) ;
446+ } while ( true ) ;
447+
448+ return UNDEFINED ;
449+ }
450+
451+
452+ /**
453+ * Try to match any mutation of |requestedLocale| against |availableLocales|.
454+ */
455+ function attemptSingleLookup ( availableLocales , requestedLocale ) {
456+ // Remove all extensions.
457+ var noExtensionsLocale = % RegExpInternalReplace (
458+ GetAnyExtensionRE ( ) , requestedLocale , '' ) ;
459+ var availableLocale = bestAvailableLocale (
460+ availableLocales , requestedLocale ) ;
461+ if ( ! IS_UNDEFINED ( availableLocale ) ) {
462+ // Return the resolved locale and extension.
463+ var extensionMatch = % regexp_internal_match (
464+ GetUnicodeExtensionRE ( ) , requestedLocale ) ;
465+ var extension = IS_NULL ( extensionMatch ) ? '' : extensionMatch [ 0 ] ;
466+ return { locale : availableLocale , extension : extension } ;
467+ }
468+ return UNDEFINED ;
469+ }
470+
471+
437472/**
438473 * Returns best matched supported locale and extension info using basic
439474 * lookup algorithm.
@@ -446,31 +481,25 @@ function lookupMatcher(service, requestedLocales) {
446481 var availableLocales = getAvailableLocalesOf ( service ) ;
447482
448483 for ( var i = 0 ; i < requestedLocales . length ; ++ i ) {
449- // Remove all extensions.
450- var locale = % RegExpInternalReplace (
451- GetAnyExtensionRE ( ) , requestedLocales [ i ] , '' ) ;
452- do {
453- if ( ! IS_UNDEFINED ( availableLocales [ locale ] ) ) {
454- // Return the resolved locale and extension.
455- var extensionMatch = % regexp_internal_match (
456- GetUnicodeExtensionRE ( ) , requestedLocales [ i ] ) ;
457- var extension = IS_NULL ( extensionMatch ) ? '' : extensionMatch [ 0 ] ;
458- return { locale : locale , extension : extension , position : i } ;
459- }
460- // Truncate locale if possible.
461- var pos = % StringLastIndexOf ( locale , '-' ) ;
462- if ( pos === - 1 ) {
463- break ;
464- }
465- locale = % _Call ( StringSubstring , locale , 0 , pos ) ;
466- } while ( true ) ;
484+ var result = attemptSingleLookup ( availableLocales , requestedLocales [ i ] ) ;
485+ if ( ! IS_UNDEFINED ( result ) ) {
486+ return result ;
487+ }
488+ }
489+
490+ var defLocale = GetDefaultICULocaleJS ( ) ;
491+
492+ // While ECMA-402 returns defLocale directly, we have to check if it is
493+ // supported, as such support is not guaranteed.
494+ var result = attemptSingleLookup ( availableLocales , defLocale ) ;
495+ if ( ! IS_UNDEFINED ( result ) ) {
496+ return result ;
467497 }
468498
469499 // Didn't find a match, return default.
470500 return {
471- locale : GetDefaultICULocaleJS ( service ) ,
472- extension : '' ,
473- position : - 1
501+ locale : 'und' ,
502+ extension : ''
474503 } ;
475504}
476505
0 commit comments