Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(161)

Unified Diff: src/js/i18n.js

Issue 1812673005: Use ICU case conversion/transliterator for case conversion behind a flag (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Yang's comment addressed - return right away for no-change Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/js/i18n.js
diff --git a/src/js/i18n.js b/src/js/i18n.js
index dc64304a7853ae318f9e4f392b0bf9a8b7f927db..d6f03fe96e8ef9b338d7441507401aa6a8292179 100644
--- a/src/js/i18n.js
+++ b/src/js/i18n.js
@@ -142,6 +142,13 @@ var AVAILABLE_LOCALES = {
*/
var DEFAULT_ICU_LOCALE = UNDEFINED;
+function GetDefaultICULocaleJS() {
+ if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
+ DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
+ }
+ return DEFAULT_ICU_LOCALE;
+}
+
/**
* Unicode extension regular expression.
*/
@@ -446,11 +453,7 @@ function lookupMatcher(service, requestedLocales) {
}
// Didn't find a match, return default.
- if (IS_UNDEFINED(DEFAULT_ICU_LOCALE)) {
- DEFAULT_ICU_LOCALE = %GetDefaultICULocale();
- }
-
- return {'locale': DEFAULT_ICU_LOCALE, 'extension': '', 'position': -1};
+ return {'locale': GetDefaultICULocaleJS(), 'extension': '', 'position': -1};
}
@@ -722,21 +725,24 @@ function toTitleCaseTimezoneLocation(location) {
*/
function canonicalizeLanguageTag(localeID) {
// null is typeof 'object' so we have to do extra check.
- if (typeof localeID !== 'string' && typeof localeID !== 'object' ||
+ if ((!IS_STRING(localeID) && !IS_RECEIVER(localeID)) ||
IS_NULL(localeID)) {
throw MakeTypeError(kLanguageID);
}
+ // Optimize for the most common case; a language code alone in
+ // the canonical form/lowercase (e.g. "en", "fil").
+ if (IS_STRING(localeID) &&
+ !IS_NULL(InternalRegExpMatch(/^[a-z]{2,3}$/, localeID))) {
+ return localeID;
+ }
+
var localeString = GlobalString(localeID);
if (isValidLanguageTag(localeString) === false) {
throw MakeRangeError(kInvalidLanguageTag, localeString);
}
- // This call will strip -kn but not -kn-true extensions.
- // ICU bug filled - http://bugs.icu-project.org/trac/ticket/9265.
- // TODO(cira): check if -u-kn-true-kc-true-kh-true still throws after
- // upgrade to ICU 4.9.
var tag = %CanonicalizeLanguageTag(localeString);
if (tag === 'invalid-tag') {
throw MakeRangeError(kInvalidLanguageTag, localeString);
@@ -1989,6 +1995,37 @@ function cachedOrNewService(service, locales, options, defaults) {
return new savedObjects[service](locales, useOptions);
}
+function LocaleConvertCase(s, locales, isToUpper) {
+ // ECMA 402 section 13.1.2 steps 1 through 12.
+ var language;
+ // Optimize for the most common two cases. initializeLocaleList() can handle
+ // them as well, but it's rather slow accounting for over 60% of
+ // toLocale{U,L}Case() and about 40% of toLocale{U,L}Case("<locale>").
srl295 2016/07/27 18:53:39 if it's slow, please file a bug in ICU to address.
+ if (IS_UNDEFINED(locales)) {
+ language = GetDefaultICULocaleJS();
+ } else if (IS_STRING(locales)) {
+ language = canonicalizeLanguageTag(locales);
+ } else {
+ var locales = initializeLocaleList(locales);
+ language = locales.length > 0 ? locales[0] : GetDefaultICULocaleJS();
+ }
+
+ // StringSplit is slower than this.
+ var pos = %_Call(StringIndexOf, language, '-');
+ if (pos != -1) {
+ language = %_Call(StringSubstring, language, 0, pos);
+ }
+
+ var CUSTOM_CASE_LANGUAGES = ['az', 'el', 'lt', 'tr'];
srl295 2016/07/27 18:53:39 Filed : http://bugs.icu-project.org/trac/ticket/12
srl295 2016/07/27 18:53:39 Why are these hard coded? This decision should be
+ var langIndex = %_Call(ArrayIndexOf, CUSTOM_CASE_LANGUAGES, language);
+ if (langIndex == -1) {
+ // language-independent case conversion.
+ return isToUpper ? %StringToUpperCaseI18N(s) : %StringToLowerCaseI18N(s);
+ }
+ return %StringLocaleConvertCase(s, isToUpper,
+ CUSTOM_CASE_LANGUAGES[langIndex]);
+}
+
/**
* Compares this and that, and returns less than 0, 0 or greater than 0 value.
* Overrides the built-in method.
@@ -2041,6 +2078,56 @@ OverrideFunction(GlobalString.prototype, 'normalize', function() {
}
);
+function ToLowerCaseI18N() {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLowerCase");
+ var s = TO_STRING(this);
+ return %StringToLowerCaseI18N(s);
+}
+
+function ToUpperCaseI18N() {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toUpperCase");
+ var s = TO_STRING(this);
+ return %StringToUpperCaseI18N(s);
+}
+
+function ToLocaleLowerCaseI18N(locales) {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleLowerCase");
+ return LocaleConvertCase(TO_STRING(this), locales, false);
+}
+
+%FunctionSetLength(ToLocaleLowerCaseI18N, 0);
+
+function ToLocaleUpperCaseI18N(locales) {
+ if (!IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor);
+ }
+ CHECK_OBJECT_COERCIBLE(this, "String.prototype.toLocaleUpperCase");
+ return LocaleConvertCase(TO_STRING(this), locales, true);
+}
+
+%FunctionSetLength(ToLocaleUpperCaseI18N, 0);
+
+%FunctionRemovePrototype(ToLowerCaseI18N);
+%FunctionRemovePrototype(ToUpperCaseI18N);
+%FunctionRemovePrototype(ToLocaleLowerCaseI18N);
+%FunctionRemovePrototype(ToLocaleUpperCaseI18N);
+
+utils.Export(function(to) {
+ to.ToLowerCaseI18N = ToLowerCaseI18N;
+ to.ToUpperCaseI18N = ToUpperCaseI18N;
+ to.ToLocaleLowerCaseI18N = ToLocaleLowerCaseI18N;
+ to.ToLocaleUpperCaseI18N = ToLocaleUpperCaseI18N;
+});
+
/**
* Formats a Number object (this) using locale and options values.
« no previous file with comments | « src/flag-definitions.h ('k') | src/js/icu-case-mapping.js » ('j') | src/runtime/runtime-i18n.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698