| 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 231 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   242     configurable: true |   242     configurable: true | 
|   243   }); |   243   }); | 
|   244 } |   244 } | 
|   245  |   245  | 
|   246  |   246  | 
|   247 /** |   247 /** | 
|   248  * Returns an intersection of locales and service supported locales. |   248  * Returns an intersection of locales and service supported locales. | 
|   249  * Parameter locales is treated as a priority list. |   249  * Parameter locales is treated as a priority list. | 
|   250  */ |   250  */ | 
|   251 function supportedLocalesOf(service, locales, options) { |   251 function supportedLocalesOf(service, locales, options) { | 
|   252   if (IS_NULL(%_CallFunction(service, GetServiceRE(), StringMatch))) { |   252   if (IS_NULL(%_Call(StringMatch, service, GetServiceRE()))) { | 
|   253     throw MakeError(kWrongServiceType, service); |   253     throw MakeError(kWrongServiceType, service); | 
|   254   } |   254   } | 
|   255  |   255  | 
|   256   // Provide defaults if matcher was not specified. |   256   // Provide defaults if matcher was not specified. | 
|   257   if (IS_UNDEFINED(options)) { |   257   if (IS_UNDEFINED(options)) { | 
|   258     options = {}; |   258     options = {}; | 
|   259   } else { |   259   } else { | 
|   260     options = TO_OBJECT(options); |   260     options = TO_OBJECT(options); | 
|   261   } |   261   } | 
|   262  |   262  | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|   290  |   290  | 
|   291 /** |   291 /** | 
|   292  * Returns the subset of the provided BCP 47 language priority list for which |   292  * Returns the subset of the provided BCP 47 language priority list for which | 
|   293  * this service has a matching locale when using the BCP 47 Lookup algorithm. |   293  * this service has a matching locale when using the BCP 47 Lookup algorithm. | 
|   294  * Locales appear in the same order in the returned list as in the input list. |   294  * Locales appear in the same order in the returned list as in the input list. | 
|   295  */ |   295  */ | 
|   296 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { |   296 function lookupSupportedLocalesOf(requestedLocales, availableLocales) { | 
|   297   var matchedLocales = []; |   297   var matchedLocales = []; | 
|   298   for (var i = 0; i < requestedLocales.length; ++i) { |   298   for (var i = 0; i < requestedLocales.length; ++i) { | 
|   299     // Remove -u- extension. |   299     // Remove -u- extension. | 
|   300     var locale = %_CallFunction(requestedLocales[i], GetUnicodeExtensionRE(), |   300     var locale = %_Call(StringReplace, | 
|   301                                 '', StringReplace); |   301                         requestedLocales[i], | 
 |   302                         GetUnicodeExtensionRE(), | 
 |   303                         ''); | 
|   302     do { |   304     do { | 
|   303       if (!IS_UNDEFINED(availableLocales[locale])) { |   305       if (!IS_UNDEFINED(availableLocales[locale])) { | 
|   304         // Push requested locale not the resolved one. |   306         // Push requested locale not the resolved one. | 
|   305         %_CallFunction(matchedLocales, requestedLocales[i], ArrayPush); |   307         %_Call(ArrayPush, matchedLocales, requestedLocales[i]); | 
|   306         break; |   308         break; | 
|   307       } |   309       } | 
|   308       // Truncate locale if possible, if not break. |   310       // Truncate locale if possible, if not break. | 
|   309       var pos = %_CallFunction(locale, '-', StringLastIndexOf); |   311       var pos = %_Call(StringLastIndexOf, locale, '-'); | 
|   310       if (pos === -1) { |   312       if (pos === -1) { | 
|   311         break; |   313         break; | 
|   312       } |   314       } | 
|   313       locale = %_CallFunction(locale, 0, pos, StringSubstring); |   315       locale = %_Call(StringSubstring, locale, 0, pos); | 
|   314     } while (true); |   316     } while (true); | 
|   315   } |   317   } | 
|   316  |   318  | 
|   317   return matchedLocales; |   319   return matchedLocales; | 
|   318 } |   320 } | 
|   319  |   321  | 
|   320  |   322  | 
|   321 /** |   323 /** | 
|   322  * Returns the subset of the provided BCP 47 language priority list for which |   324  * Returns the subset of the provided BCP 47 language priority list for which | 
|   323  * this service has a matching locale when using the implementation |   325  * this service has a matching locale when using the implementation | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|   348         case 'string': |   350         case 'string': | 
|   349           value = GlobalString(value); |   351           value = GlobalString(value); | 
|   350           break; |   352           break; | 
|   351         case 'number': |   353         case 'number': | 
|   352           value = GlobalNumber(value); |   354           value = GlobalNumber(value); | 
|   353           break; |   355           break; | 
|   354         default: |   356         default: | 
|   355           throw MakeError(kWrongValueType); |   357           throw MakeError(kWrongValueType); | 
|   356       } |   358       } | 
|   357  |   359  | 
|   358       if (!IS_UNDEFINED(values) && |   360       if (!IS_UNDEFINED(values) && %_Call(ArrayIndexOf, values, value) === -1) { | 
|   359           %_CallFunction(values, value, ArrayIndexOf) === -1) { |  | 
|   360         throw MakeRangeError(kValueOutOfRange, value, caller, property); |   361         throw MakeRangeError(kValueOutOfRange, value, caller, property); | 
|   361       } |   362       } | 
|   362  |   363  | 
|   363       return value; |   364       return value; | 
|   364     } |   365     } | 
|   365  |   366  | 
|   366     return defaultValue; |   367     return defaultValue; | 
|   367   } |   368   } | 
|   368  |   369  | 
|   369   return getOption; |   370   return getOption; | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
|   398  |   399  | 
|   399   return resolved; |   400   return resolved; | 
|   400 } |   401 } | 
|   401  |   402  | 
|   402  |   403  | 
|   403 /** |   404 /** | 
|   404  * Returns best matched supported locale and extension info using basic |   405  * Returns best matched supported locale and extension info using basic | 
|   405  * lookup algorithm. |   406  * lookup algorithm. | 
|   406  */ |   407  */ | 
|   407 function lookupMatcher(service, requestedLocales) { |   408 function lookupMatcher(service, requestedLocales) { | 
|   408   if (IS_NULL(%_CallFunction(service, GetServiceRE(), StringMatch))) { |   409   if (IS_NULL(%_Call(StringMatch, service, GetServiceRE()))) { | 
|   409     throw MakeError(kWrongServiceType, service); |   410     throw MakeError(kWrongServiceType, service); | 
|   410   } |   411   } | 
|   411  |   412  | 
|   412   // Cache these, they don't ever change per service. |   413   // Cache these, they don't ever change per service. | 
|   413   if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) { |   414   if (IS_UNDEFINED(AVAILABLE_LOCALES[service])) { | 
|   414     AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); |   415     AVAILABLE_LOCALES[service] = getAvailableLocalesOf(service); | 
|   415   } |   416   } | 
|   416  |   417  | 
|   417   for (var i = 0; i < requestedLocales.length; ++i) { |   418   for (var i = 0; i < requestedLocales.length; ++i) { | 
|   418     // Remove all extensions. |   419     // Remove all extensions. | 
|   419     var locale = %_CallFunction(requestedLocales[i], GetAnyExtensionRE(), '', |   420     var locale = %_Call(StringReplace, requestedLocales[i], | 
|   420                                 StringReplace); |   421                         GetAnyExtensionRE(), ''); | 
|   421     do { |   422     do { | 
|   422       if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) { |   423       if (!IS_UNDEFINED(AVAILABLE_LOCALES[service][locale])) { | 
|   423         // Return the resolved locale and extension. |   424         // Return the resolved locale and extension. | 
|   424         var extensionMatch = |   425         var extensionMatch = | 
|   425             %_CallFunction(requestedLocales[i], GetUnicodeExtensionRE(), |   426             %_Call(StringMatch, requestedLocales[i], GetUnicodeExtensionRE()); | 
|   426                            StringMatch); |  | 
|   427         var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; |   427         var extension = IS_NULL(extensionMatch) ? '' : extensionMatch[0]; | 
|   428         return {'locale': locale, 'extension': extension, 'position': i}; |   428         return {'locale': locale, 'extension': extension, 'position': i}; | 
|   429       } |   429       } | 
|   430       // Truncate locale if possible. |   430       // Truncate locale if possible. | 
|   431       var pos = %_CallFunction(locale, '-', StringLastIndexOf); |   431       var pos = %_Call(StringLastIndexOf, locale, '-'); | 
|   432       if (pos === -1) { |   432       if (pos === -1) { | 
|   433         break; |   433         break; | 
|   434       } |   434       } | 
|   435       locale = %_CallFunction(locale, 0, pos, StringSubstring); |   435       locale = %_Call(StringSubstring, locale, 0, pos); | 
|   436     } while (true); |   436     } while (true); | 
|   437   } |   437   } | 
|   438  |   438  | 
|   439   // Didn't find a match, return default. |   439   // Didn't find a match, return default. | 
|   440   if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) { |   440   if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) { | 
|   441     DEFAULT_ICU_LOCALE = %GetDefaultICULocale(); |   441     DEFAULT_ICU_LOCALE = %GetDefaultICULocale(); | 
|   442   } |   442   } | 
|   443  |   443  | 
|   444   return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1}; |   444   return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1}; | 
|   445 } |   445 } | 
|   446  |   446  | 
|   447  |   447  | 
|   448 /** |   448 /** | 
|   449  * Returns best matched supported locale and extension info using |   449  * Returns best matched supported locale and extension info using | 
|   450  * implementation dependend algorithm. |   450  * implementation dependend algorithm. | 
|   451  */ |   451  */ | 
|   452 function bestFitMatcher(service, requestedLocales) { |   452 function bestFitMatcher(service, requestedLocales) { | 
|   453   // TODO(cira): implement better best fit algorithm. |   453   // TODO(cira): implement better best fit algorithm. | 
|   454   return lookupMatcher(service, requestedLocales); |   454   return lookupMatcher(service, requestedLocales); | 
|   455 } |   455 } | 
|   456  |   456  | 
|   457  |   457  | 
|   458 /** |   458 /** | 
|   459  * Parses Unicode extension into key - value map. |   459  * Parses Unicode extension into key - value map. | 
|   460  * Returns empty object if the extension string is invalid. |   460  * Returns empty object if the extension string is invalid. | 
|   461  * We are not concerned with the validity of the values at this point. |   461  * We are not concerned with the validity of the values at this point. | 
|   462  */ |   462  */ | 
|   463 function parseExtension(extension) { |   463 function parseExtension(extension) { | 
|   464   var extensionSplit = %_CallFunction(extension, '-', StringSplit); |   464   var extensionSplit = %_Call(StringSplit, extension, '-'); | 
|   465  |   465  | 
|   466   // Assume ['', 'u', ...] input, but don't throw. |   466   // Assume ['', 'u', ...] input, but don't throw. | 
|   467   if (extensionSplit.length <= 2 || |   467   if (extensionSplit.length <= 2 || | 
|   468       (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) { |   468       (extensionSplit[0] !== '' && extensionSplit[1] !== 'u')) { | 
|   469     return {}; |   469     return {}; | 
|   470   } |   470   } | 
|   471  |   471  | 
|   472   // Key is {2}alphanum, value is {3,8}alphanum. |   472   // Key is {2}alphanum, value is {3,8}alphanum. | 
|   473   // Some keys may not have explicit values (booleans). |   473   // Some keys may not have explicit values (booleans). | 
|   474   var extensionMap = {}; |   474   var extensionMap = {}; | 
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   591     return original; |   591     return original; | 
|   592   } |   592   } | 
|   593  |   593  | 
|   594   var locales = %GetLanguageTagVariants([original, resolved]); |   594   var locales = %GetLanguageTagVariants([original, resolved]); | 
|   595   if (locales[0].maximized !== locales[1].maximized) { |   595   if (locales[0].maximized !== locales[1].maximized) { | 
|   596     return resolved; |   596     return resolved; | 
|   597   } |   597   } | 
|   598  |   598  | 
|   599   // Preserve extensions of resolved locale, but swap base tags with original. |   599   // Preserve extensions of resolved locale, but swap base tags with original. | 
|   600   var resolvedBase = new GlobalRegExp('^' + locales[1].base); |   600   var resolvedBase = new GlobalRegExp('^' + locales[1].base); | 
|   601   return %_CallFunction(resolved, resolvedBase, locales[0].base, StringReplace); |   601   return %_Call(StringReplace, resolved, resolvedBase, locales[0].base); | 
|   602 } |   602 } | 
|   603  |   603  | 
|   604  |   604  | 
|   605 /** |   605 /** | 
|   606  * Returns an Object that contains all of supported locales for a given |   606  * Returns an Object that contains all of supported locales for a given | 
|   607  * service. |   607  * service. | 
|   608  * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ |   608  * In addition to the supported locales we add xx-ZZ locale for each xx-Yyyy-ZZ | 
|   609  * that is supported. This is required by the spec. |   609  * that is supported. This is required by the spec. | 
|   610  */ |   610  */ | 
|   611 function getAvailableLocalesOf(service) { |   611 function getAvailableLocalesOf(service) { | 
|   612   var available = %AvailableLocalesOf(service); |   612   var available = %AvailableLocalesOf(service); | 
|   613  |   613  | 
|   614   for (var i in available) { |   614   for (var i in available) { | 
|   615     if (%HasOwnProperty(available, i)) { |   615     if (%HasOwnProperty(available, i)) { | 
|   616       var parts = %_CallFunction(i, /^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/, |   616       var parts = | 
|   617                                  StringMatch); |   617           %_Call(StringMatch, i, /^([a-z]{2,3})-([A-Z][a-z]{3})-([A-Z]{2})$/); | 
|   618       if (parts !== null) { |   618       if (parts !== null) { | 
|   619         // Build xx-ZZ. We don't care about the actual value, |   619         // Build xx-ZZ. We don't care about the actual value, | 
|   620         // as long it's not undefined. |   620         // as long it's not undefined. | 
|   621         available[parts[1] + '-' + parts[3]] = null; |   621         available[parts[1] + '-' + parts[3]] = null; | 
|   622       } |   622       } | 
|   623     } |   623     } | 
|   624   } |   624   } | 
|   625  |   625  | 
|   626   return available; |   626   return available; | 
|   627 } |   627 } | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   667   if (!IS_UNDEFINED(value)) { |   667   if (!IS_UNDEFINED(value)) { | 
|   668     defineWECProperty(object, property, value); |   668     defineWECProperty(object, property, value); | 
|   669   } |   669   } | 
|   670 } |   670 } | 
|   671  |   671  | 
|   672  |   672  | 
|   673 /** |   673 /** | 
|   674  * Returns titlecased word, aMeRricA -> America. |   674  * Returns titlecased word, aMeRricA -> America. | 
|   675  */ |   675  */ | 
|   676 function toTitleCaseWord(word) { |   676 function toTitleCaseWord(word) { | 
|   677   return %StringToUpperCase(%_CallFunction(word, 0, 1, StringSubstr)) + |   677   return %StringToUpperCase(%_Call(StringSubstr, word, 0, 1)) + | 
|   678          %StringToLowerCase(%_CallFunction(word, 1, StringSubstr)); |   678          %StringToLowerCase(%_Call(StringSubstr, word, 1)); | 
|   679 } |   679 } | 
|   680  |   680  | 
|   681 /** |   681 /** | 
|   682  * Canonicalizes the language tag, or throws in case the tag is invalid. |   682  * Canonicalizes the language tag, or throws in case the tag is invalid. | 
|   683  */ |   683  */ | 
|   684 function canonicalizeLanguageTag(localeID) { |   684 function canonicalizeLanguageTag(localeID) { | 
|   685   // null is typeof 'object' so we have to do extra check. |   685   // null is typeof 'object' so we have to do extra check. | 
|   686   if (typeof localeID !== 'string' && typeof localeID !== 'object' || |   686   if (typeof localeID !== 'string' && typeof localeID !== 'object' || | 
|   687       IS_NULL(localeID)) { |   687       IS_NULL(localeID)) { | 
|   688     throw MakeTypeError(kLanguageID); |   688     throw MakeTypeError(kLanguageID); | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
|   712  * Throws on locales that are not well formed BCP47 tags. |   712  * Throws on locales that are not well formed BCP47 tags. | 
|   713  */ |   713  */ | 
|   714 function initializeLocaleList(locales) { |   714 function initializeLocaleList(locales) { | 
|   715   var seen = []; |   715   var seen = []; | 
|   716   if (IS_UNDEFINED(locales)) { |   716   if (IS_UNDEFINED(locales)) { | 
|   717     // Constructor is called without arguments. |   717     // Constructor is called without arguments. | 
|   718     seen = []; |   718     seen = []; | 
|   719   } else { |   719   } else { | 
|   720     // We allow single string localeID. |   720     // We allow single string localeID. | 
|   721     if (typeof locales === 'string') { |   721     if (typeof locales === 'string') { | 
|   722       %_CallFunction(seen, canonicalizeLanguageTag(locales), ArrayPush); |   722       %_Call(ArrayPush, seen, canonicalizeLanguageTag(locales)); | 
|   723       return freezeArray(seen); |   723       return freezeArray(seen); | 
|   724     } |   724     } | 
|   725  |   725  | 
|   726     var o = TO_OBJECT(locales); |   726     var o = TO_OBJECT(locales); | 
|   727     var len = TO_UINT32(o.length); |   727     var len = TO_UINT32(o.length); | 
|   728  |   728  | 
|   729     for (var k = 0; k < len; k++) { |   729     for (var k = 0; k < len; k++) { | 
|   730       if (k in o) { |   730       if (k in o) { | 
|   731         var value = o[k]; |   731         var value = o[k]; | 
|   732  |   732  | 
|   733         var tag = canonicalizeLanguageTag(value); |   733         var tag = canonicalizeLanguageTag(value); | 
|   734  |   734  | 
|   735         if (%_CallFunction(seen, tag, ArrayIndexOf) === -1) { |   735         if (%_Call(ArrayIndexOf, seen, tag) === -1) { | 
|   736           %_CallFunction(seen, tag, ArrayPush); |   736           %_Call(ArrayPush, seen, tag); | 
|   737         } |   737         } | 
|   738       } |   738       } | 
|   739     } |   739     } | 
|   740   } |   740   } | 
|   741  |   741  | 
|   742   return freezeArray(seen); |   742   return freezeArray(seen); | 
|   743 } |   743 } | 
|   744  |   744  | 
|   745  |   745  | 
|   746 /** |   746 /** | 
|   747  * Validates the language tag. Section 2.2.9 of the bcp47 spec |   747  * Validates the language tag. Section 2.2.9 of the bcp47 spec | 
|   748  * defines a valid tag. |   748  * defines a valid tag. | 
|   749  * |   749  * | 
|   750  * ICU is too permissible and lets invalid tags, like |   750  * ICU is too permissible and lets invalid tags, like | 
|   751  * hant-cmn-cn, through. |   751  * hant-cmn-cn, through. | 
|   752  * |   752  * | 
|   753  * Returns false if the language tag is invalid. |   753  * Returns false if the language tag is invalid. | 
|   754  */ |   754  */ | 
|   755 function isValidLanguageTag(locale) { |   755 function isValidLanguageTag(locale) { | 
|   756   // Check if it's well-formed, including grandfadered tags. |   756   // Check if it's well-formed, including grandfadered tags. | 
|   757   if (!%_CallFunction(GetLanguageTagRE(), locale, RegExpTest)) { |   757   if (!%_Call(RegExpTest, GetLanguageTagRE(), locale)) { | 
|   758     return false; |   758     return false; | 
|   759   } |   759   } | 
|   760  |   760  | 
|   761   // Just return if it's a x- form. It's all private. |   761   // Just return if it's a x- form. It's all private. | 
|   762   if (%_CallFunction(locale, 'x-', StringIndexOf) === 0) { |   762   if (%_Call(StringIndexOf, locale, 'x-') === 0) { | 
|   763     return true; |   763     return true; | 
|   764   } |   764   } | 
|   765  |   765  | 
|   766   // Check if there are any duplicate variants or singletons (extensions). |   766   // Check if there are any duplicate variants or singletons (extensions). | 
|   767  |   767  | 
|   768   // Remove private use section. |   768   // Remove private use section. | 
|   769   locale = %_CallFunction(locale, /-x-/, StringSplit)[0]; |   769   locale = %_Call(StringSplit, locale, /-x-/)[0]; | 
|   770  |   770  | 
|   771   // Skip language since it can match variant regex, so we start from 1. |   771   // Skip language since it can match variant regex, so we start from 1. | 
|   772   // We are matching i-klingon here, but that's ok, since i-klingon-klingon |   772   // We are matching i-klingon here, but that's ok, since i-klingon-klingon | 
|   773   // is not valid and would fail LANGUAGE_TAG_RE test. |   773   // is not valid and would fail LANGUAGE_TAG_RE test. | 
|   774   var variants = []; |   774   var variants = []; | 
|   775   var extensions = []; |   775   var extensions = []; | 
|   776   var parts = %_CallFunction(locale, /-/, StringSplit); |   776   var parts = %_Call(StringSplit, locale, /-/); | 
|   777   for (var i = 1; i < parts.length; i++) { |   777   for (var i = 1; i < parts.length; i++) { | 
|   778     var value = parts[i]; |   778     var value = parts[i]; | 
|   779     if (%_CallFunction(GetLanguageVariantRE(), value, RegExpTest) && |   779     if (%_Call(RegExpTest, GetLanguageVariantRE(), value) && | 
|   780         extensions.length === 0) { |   780         extensions.length === 0) { | 
|   781       if (%_CallFunction(variants, value, ArrayIndexOf) === -1) { |   781       if (%_Call(ArrayIndexOf, variants, value) === -1) { | 
|   782         %_CallFunction(variants, value, ArrayPush); |   782         %_Call(ArrayPush, variants, value); | 
|   783       } else { |   783       } else { | 
|   784         return false; |   784         return false; | 
|   785       } |   785       } | 
|   786     } |   786     } | 
|   787  |   787  | 
|   788     if (%_CallFunction(GetLanguageSingletonRE(), value, RegExpTest)) { |   788     if (%_Call(RegExpTest, GetLanguageSingletonRE(), value)) { | 
|   789       if (%_CallFunction(extensions, value, ArrayIndexOf) === -1) { |   789       if (%_Call(ArrayIndexOf, extensions, value) === -1) { | 
|   790         %_CallFunction(extensions, value, ArrayPush); |   790         %_Call(ArrayPush, extensions, value); | 
|   791       } else { |   791       } else { | 
|   792         return false; |   792         return false; | 
|   793       } |   793       } | 
|   794     } |   794     } | 
|   795   } |   795   } | 
|   796  |   796  | 
|   797   return true; |   797   return true; | 
|   798  } |   798  } | 
|   799  |   799  | 
|   800  |   800  | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   894  |   894  | 
|   895     /** |   895     /** | 
|   896      * Allowed -u-co- values. List taken from: |   896      * Allowed -u-co- values. List taken from: | 
|   897      * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml |   897      * http://unicode.org/repos/cldr/trunk/common/bcp47/collation.xml | 
|   898      */ |   898      */ | 
|   899     var ALLOWED_CO_VALUES = [ |   899     var ALLOWED_CO_VALUES = [ | 
|   900       'big5han', 'dict', 'direct', 'ducet', 'gb2312', 'phonebk', 'phonetic', |   900       'big5han', 'dict', 'direct', 'ducet', 'gb2312', 'phonebk', 'phonetic', | 
|   901       'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin' |   901       'pinyin', 'reformed', 'searchjl', 'stroke', 'trad', 'unihan', 'zhuyin' | 
|   902     ]; |   902     ]; | 
|   903  |   903  | 
|   904     if (%_CallFunction(ALLOWED_CO_VALUES, extensionMap.co, ArrayIndexOf) !== |   904     if (%_Call(ArrayIndexOf, ALLOWED_CO_VALUES, extensionMap.co) !== -1) { | 
|   905         -1) { |  | 
|   906       extension = '-u-co-' + extensionMap.co; |   905       extension = '-u-co-' + extensionMap.co; | 
|   907       // ICU can't tell us what the collation is, so save user's input. |   906       // ICU can't tell us what the collation is, so save user's input. | 
|   908       collation = extensionMap.co; |   907       collation = extensionMap.co; | 
|   909     } |   908     } | 
|   910   } else if (internalOptions.usage === 'search') { |   909   } else if (internalOptions.usage === 'search') { | 
|   911     extension = '-u-co-search'; |   910     extension = '-u-co-search'; | 
|   912   } |   911   } | 
|   913   defineWEProperty(internalOptions, 'collation', collation); |   912   defineWEProperty(internalOptions, 'collation', collation); | 
|   914  |   913  | 
|   915   var requestedLocale = locale.locale + extension; |   914   var requestedLocale = locale.locale + extension; | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1035 addBoundMethod(Intl.Collator, 'compare', compare, 2); |  1034 addBoundMethod(Intl.Collator, 'compare', compare, 2); | 
|  1036  |  1035  | 
|  1037 /** |  1036 /** | 
|  1038  * Verifies that the input is a well-formed ISO 4217 currency code. |  1037  * Verifies that the input is a well-formed ISO 4217 currency code. | 
|  1039  * Don't uppercase to test. It could convert invalid code into a valid one. |  1038  * Don't uppercase to test. It could convert invalid code into a valid one. | 
|  1040  * For example \u00DFP (Eszett+P) becomes SSP. |  1039  * For example \u00DFP (Eszett+P) becomes SSP. | 
|  1041  */ |  1040  */ | 
|  1042 function isWellFormedCurrencyCode(currency) { |  1041 function isWellFormedCurrencyCode(currency) { | 
|  1043   return typeof currency == "string" && |  1042   return typeof currency == "string" && | 
|  1044       currency.length == 3 && |  1043       currency.length == 3 && | 
|  1045       %_CallFunction(currency, /[^A-Za-z]/, StringMatch) == null; |  1044       %_Call(StringMatch, currency, /[^A-Za-z]/) == null; | 
|  1046 } |  1045 } | 
|  1047  |  1046  | 
|  1048  |  1047  | 
|  1049 /** |  1048 /** | 
|  1050  * Returns the valid digit count for a property, or throws RangeError on |  1049  * Returns the valid digit count for a property, or throws RangeError on | 
|  1051  * a value out of the range. |  1050  * a value out of the range. | 
|  1052  */ |  1051  */ | 
|  1053 function getNumberOption(options, property, min, max, fallback) { |  1052 function getNumberOption(options, property, min, max, fallback) { | 
|  1054   var value = options[property]; |  1053   var value = options[property]; | 
|  1055   if (!IS_UNDEFINED(value)) { |  1054   if (!IS_UNDEFINED(value)) { | 
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1364     return ''; |  1363     return ''; | 
|  1365   } |  1364   } | 
|  1366 } |  1365 } | 
|  1367  |  1366  | 
|  1368  |  1367  | 
|  1369 /** |  1368 /** | 
|  1370  * Returns object that matches LDML representation of the date. |  1369  * Returns object that matches LDML representation of the date. | 
|  1371  */ |  1370  */ | 
|  1372 function fromLDMLString(ldmlString) { |  1371 function fromLDMLString(ldmlString) { | 
|  1373   // First remove '' quoted text, so we lose 'Uhr' strings. |  1372   // First remove '' quoted text, so we lose 'Uhr' strings. | 
|  1374   ldmlString = %_CallFunction(ldmlString, GetQuotedStringRE(), '', |  1373   ldmlString = %_Call(StringReplace, ldmlString, GetQuotedStringRE(), ''); | 
|  1375                               StringReplace); |  | 
|  1376  |  1374  | 
|  1377   var options = {}; |  1375   var options = {}; | 
|  1378   var match = %_CallFunction(ldmlString, /E{3,5}/g, StringMatch); |  1376   var match = %_Call(StringMatch, ldmlString, /E{3,5}/g); | 
|  1379   options = appendToDateTimeObject( |  1377   options = appendToDateTimeObject( | 
|  1380       options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'}); |  1378       options, 'weekday', match, {EEEEE: 'narrow', EEE: 'short', EEEE: 'long'}); | 
|  1381  |  1379  | 
|  1382   match = %_CallFunction(ldmlString, /G{3,5}/g, StringMatch); |  1380   match = %_Call(StringMatch, ldmlString, /G{3,5}/g); | 
|  1383   options = appendToDateTimeObject( |  1381   options = appendToDateTimeObject( | 
|  1384       options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'}); |  1382       options, 'era', match, {GGGGG: 'narrow', GGG: 'short', GGGG: 'long'}); | 
|  1385  |  1383  | 
|  1386   match = %_CallFunction(ldmlString, /y{1,2}/g, StringMatch); |  1384   match = %_Call(StringMatch, ldmlString, /y{1,2}/g); | 
|  1387   options = appendToDateTimeObject( |  1385   options = appendToDateTimeObject( | 
|  1388       options, 'year', match, {y: 'numeric', yy: '2-digit'}); |  1386       options, 'year', match, {y: 'numeric', yy: '2-digit'}); | 
|  1389  |  1387  | 
|  1390   match = %_CallFunction(ldmlString, /M{1,5}/g, StringMatch); |  1388   match = %_Call(StringMatch, ldmlString, /M{1,5}/g); | 
|  1391   options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit', |  1389   options = appendToDateTimeObject(options, 'month', match, {MM: '2-digit', | 
|  1392       M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'}); |  1390       M: 'numeric', MMMMM: 'narrow', MMM: 'short', MMMM: 'long'}); | 
|  1393  |  1391  | 
|  1394   // Sometimes we get L instead of M for month - standalone name. |  1392   // Sometimes we get L instead of M for month - standalone name. | 
|  1395   match = %_CallFunction(ldmlString, /L{1,5}/g, StringMatch); |  1393   match = %_Call(StringMatch, ldmlString, /L{1,5}/g); | 
|  1396   options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit', |  1394   options = appendToDateTimeObject(options, 'month', match, {LL: '2-digit', | 
|  1397       L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'}); |  1395       L: 'numeric', LLLLL: 'narrow', LLL: 'short', LLLL: 'long'}); | 
|  1398  |  1396  | 
|  1399   match = %_CallFunction(ldmlString, /d{1,2}/g, StringMatch); |  1397   match = %_Call(StringMatch, ldmlString, /d{1,2}/g); | 
|  1400   options = appendToDateTimeObject( |  1398   options = appendToDateTimeObject( | 
|  1401       options, 'day', match, {d: 'numeric', dd: '2-digit'}); |  1399       options, 'day', match, {d: 'numeric', dd: '2-digit'}); | 
|  1402  |  1400  | 
|  1403   match = %_CallFunction(ldmlString, /h{1,2}/g, StringMatch); |  1401   match = %_Call(StringMatch, ldmlString, /h{1,2}/g); | 
|  1404   if (match !== null) { |  1402   if (match !== null) { | 
|  1405     options['hour12'] = true; |  1403     options['hour12'] = true; | 
|  1406   } |  1404   } | 
|  1407   options = appendToDateTimeObject( |  1405   options = appendToDateTimeObject( | 
|  1408       options, 'hour', match, {h: 'numeric', hh: '2-digit'}); |  1406       options, 'hour', match, {h: 'numeric', hh: '2-digit'}); | 
|  1409  |  1407  | 
|  1410   match = %_CallFunction(ldmlString, /H{1,2}/g, StringMatch); |  1408   match = %_Call(StringMatch, ldmlString, /H{1,2}/g); | 
|  1411   if (match !== null) { |  1409   if (match !== null) { | 
|  1412     options['hour12'] = false; |  1410     options['hour12'] = false; | 
|  1413   } |  1411   } | 
|  1414   options = appendToDateTimeObject( |  1412   options = appendToDateTimeObject( | 
|  1415       options, 'hour', match, {H: 'numeric', HH: '2-digit'}); |  1413       options, 'hour', match, {H: 'numeric', HH: '2-digit'}); | 
|  1416  |  1414  | 
|  1417   match = %_CallFunction(ldmlString, /m{1,2}/g, StringMatch); |  1415   match = %_Call(StringMatch, ldmlString, /m{1,2}/g); | 
|  1418   options = appendToDateTimeObject( |  1416   options = appendToDateTimeObject( | 
|  1419       options, 'minute', match, {m: 'numeric', mm: '2-digit'}); |  1417       options, 'minute', match, {m: 'numeric', mm: '2-digit'}); | 
|  1420  |  1418  | 
|  1421   match = %_CallFunction(ldmlString, /s{1,2}/g, StringMatch); |  1419   match = %_Call(StringMatch, ldmlString, /s{1,2}/g); | 
|  1422   options = appendToDateTimeObject( |  1420   options = appendToDateTimeObject( | 
|  1423       options, 'second', match, {s: 'numeric', ss: '2-digit'}); |  1421       options, 'second', match, {s: 'numeric', ss: '2-digit'}); | 
|  1424  |  1422  | 
|  1425   match = %_CallFunction(ldmlString, /z|zzzz/g, StringMatch); |  1423   match = %_Call(StringMatch, ldmlString, /z|zzzz/g); | 
|  1426   options = appendToDateTimeObject( |  1424   options = appendToDateTimeObject( | 
|  1427       options, 'timeZoneName', match, {z: 'short', zzzz: 'long'}); |  1425       options, 'timeZoneName', match, {z: 'short', zzzz: 'long'}); | 
|  1428  |  1426  | 
|  1429   return options; |  1427   return options; | 
|  1430 } |  1428 } | 
|  1431  |  1429  | 
|  1432  |  1430  | 
|  1433 function appendToDateTimeObject(options, option, match, pairs) { |  1431 function appendToDateTimeObject(options, option, match, pairs) { | 
|  1434   if (IS_NULL(match)) { |  1432   if (IS_NULL(match)) { | 
|  1435     if (!%HasOwnProperty(options, option)) { |  1433     if (!%HasOwnProperty(options, option)) { | 
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1748  |  1746  | 
|  1749   // Special case handling (UTC, GMT). |  1747   // Special case handling (UTC, GMT). | 
|  1750   var upperID = %StringToUpperCase(tzID); |  1748   var upperID = %StringToUpperCase(tzID); | 
|  1751   if (upperID === 'UTC' || upperID === 'GMT' || |  1749   if (upperID === 'UTC' || upperID === 'GMT' || | 
|  1752       upperID === 'ETC/UTC' || upperID === 'ETC/GMT') { |  1750       upperID === 'ETC/UTC' || upperID === 'ETC/GMT') { | 
|  1753     return 'UTC'; |  1751     return 'UTC'; | 
|  1754   } |  1752   } | 
|  1755  |  1753  | 
|  1756   // We expect only _ and / beside ASCII letters. |  1754   // We expect only _ and / beside ASCII letters. | 
|  1757   // All inputs should conform to Area/Location from now on. |  1755   // All inputs should conform to Area/Location from now on. | 
|  1758   var match = %_CallFunction(tzID, GetTimezoneNameCheckRE(), StringMatch); |  1756   var match = %_Call(StringMatch, tzID, GetTimezoneNameCheckRE()); | 
|  1759   if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID); |  1757   if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID); | 
|  1760  |  1758  | 
|  1761   var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]); |  1759   var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]); | 
|  1762   var i = 3; |  1760   var i = 3; | 
|  1763   while (!IS_UNDEFINED(match[i]) && i < match.length) { |  1761   while (!IS_UNDEFINED(match[i]) && i < match.length) { | 
|  1764     result = result + '_' + toTitleCaseWord(match[i]); |  1762     result = result + '_' + toTitleCaseWord(match[i]); | 
|  1765     i++; |  1763     i++; | 
|  1766   } |  1764   } | 
|  1767  |  1765  | 
|  1768   return result; |  1766   return result; | 
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2010     } |  2008     } | 
|  2011  |  2009  | 
|  2012     CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); |  2010     CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); | 
|  2013     var s = TO_STRING(this); |  2011     var s = TO_STRING(this); | 
|  2014  |  2012  | 
|  2015     var formArg = %_Arguments(0); |  2013     var formArg = %_Arguments(0); | 
|  2016     var form = IS_UNDEFINED(formArg) ? 'NFC' : TO_STRING(formArg); |  2014     var form = IS_UNDEFINED(formArg) ? 'NFC' : TO_STRING(formArg); | 
|  2017  |  2015  | 
|  2018     var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; |  2016     var NORMALIZATION_FORMS = ['NFC', 'NFD', 'NFKC', 'NFKD']; | 
|  2019  |  2017  | 
|  2020     var normalizationForm = |  2018     var normalizationForm = %_Call(ArrayIndexOf, NORMALIZATION_FORMS, form); | 
|  2021         %_CallFunction(NORMALIZATION_FORMS, form, ArrayIndexOf); |  | 
|  2022     if (normalizationForm === -1) { |  2019     if (normalizationForm === -1) { | 
|  2023       throw MakeRangeError(kNormalizationForm, |  2020       throw MakeRangeError(kNormalizationForm, | 
|  2024           %_CallFunction(NORMALIZATION_FORMS, ', ', ArrayJoin)); |  2021           %_Call(ArrayJoin, NORMALIZATION_FORMS, ', ')); | 
|  2025     } |  2022     } | 
|  2026  |  2023  | 
|  2027     return %StringNormalize(s, normalizationForm); |  2024     return %StringNormalize(s, normalizationForm); | 
|  2028   } |  2025   } | 
|  2029 ); |  2026 ); | 
|  2030  |  2027  | 
|  2031  |  2028  | 
|  2032 /** |  2029 /** | 
|  2033  * Formats a Number object (this) using locale and options values. |  2030  * Formats a Number object (this) using locale and options values. | 
|  2034  * If locale or options are omitted, defaults are used. |  2031  * If locale or options are omitted, defaults are used. | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2116     } |  2113     } | 
|  2117  |  2114  | 
|  2118     var locales = %_Arguments(0); |  2115     var locales = %_Arguments(0); | 
|  2119     var options = %_Arguments(1); |  2116     var options = %_Arguments(1); | 
|  2120     return toLocaleDateTime( |  2117     return toLocaleDateTime( | 
|  2121         this, locales, options, 'time', 'time', 'dateformattime'); |  2118         this, locales, options, 'time', 'time', 'dateformattime'); | 
|  2122   } |  2119   } | 
|  2123 ); |  2120 ); | 
|  2124  |  2121  | 
|  2125 }) |  2122 }) | 
| OLD | NEW |