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

Unified Diff: src/js/i18n.js

Issue 1529363005: tzname check fix (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: todo comment added for Etc/GMT{offset} Created 5 years 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
« no previous file with comments | « no previous file | src/messages.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/js/i18n.js
diff --git a/src/js/i18n.js b/src/js/i18n.js
index a859a9fbeb9f1028e0c6245364a800651d8e7f29..c32e8f18e6938a4f396350c3bef3181cfe14ee8a 100644
--- a/src/js/i18n.js
+++ b/src/js/i18n.js
@@ -176,13 +176,26 @@ var TIMEZONE_NAME_CHECK_RE = UNDEFINED;
function GetTimezoneNameCheckRE() {
if (IS_UNDEFINED(TIMEZONE_NAME_CHECK_RE)) {
- TIMEZONE_NAME_CHECK_RE =
- new GlobalRegExp('^([A-Za-z]+)/([A-Za-z]+)(?:_([A-Za-z]+))*$');
+ TIMEZONE_NAME_CHECK_RE = new GlobalRegExp(
+ '^([A-Za-z]+)/([A-Za-z_-]+)((?:\/[A-Za-z_-]+)+)*$');
}
return TIMEZONE_NAME_CHECK_RE;
}
/**
+ * Matches valid location parts of IANA time zone names.
+ */
+var TIMEZONE_NAME_LOCATION_PART_RE = UNDEFINED;
+
+function GetTimezoneNameLocationPartRE() {
+ if (IS_UNDEFINED(TIMEZONE_NAME_LOCATION_PART_RE)) {
+ TIMEZONE_NAME_LOCATION_PART_RE =
+ new GlobalRegExp('^([A-Za-z]+)((?:[_-][A-Za-z]+)+)*$');
+ }
+ return TIMEZONE_NAME_LOCATION_PART_RE;
+}
+
+/**
* Adds bound method to the prototype of the given object.
*/
function addBoundMethod(obj, methodName, implementation, length) {
@@ -679,6 +692,34 @@ function toTitleCaseWord(word) {
}
/**
+ * Returns titlecased location, bueNos_airES -> Buenos_Aires
+ * or ho_cHi_minH -> Ho_Chi_Minh. It is locale-agnostic and only
+ * deals with ASCII only characters.
+ * 'of', 'au' and 'es' are special-cased and lowercased.
+ */
+function toTitleCaseTimezoneLocation(location) {
+ var match = %_Call(StringMatch, location, GetTimezoneNameLocationPartRE());
+ if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, location);
+
+ var result = toTitleCaseWord(match[1]);
+ if (!IS_UNDEFINED(match[2]) && 2 < match.length) {
+ // The first character is a separator, '_' or '-'.
+ // None of IANA zone names has both '_' and '-'.
+ var separator = %_Call(StringSubstring, match[2], 0, 1);
+ var parts = %_Call(StringSplit, match[2], separator);
+ for (var i = 1; i < parts.length; i++) {
+ var part = parts[i]
+ var lowercasedPart = %StringToLowerCase(part);
+ result = result + separator +
+ ((lowercasedPart !== 'es' &&
+ lowercasedPart !== 'of' && lowercasedPart !== 'au') ?
+ toTitleCaseWord(part) : lowercasedPart);
+ }
+ }
+ return result;
+}
+
+/**
* Canonicalizes the language tag, or throws in case the tag is invalid.
*/
function canonicalizeLanguageTag(localeID) {
@@ -1735,8 +1776,8 @@ addBoundMethod(Intl.DateTimeFormat, 'v8Parse', parseDate, 1);
/**
- * Returns canonical Area/Location name, or throws an exception if the zone
- * name is invalid IANA name.
+ * Returns canonical Area/Location(/Location) name, or throws an exception
+ * if the zone name is invalid IANA name.
*/
function canonicalizeTimeZoneID(tzID) {
// Skip undefined zones.
@@ -1751,16 +1792,22 @@ function canonicalizeTimeZoneID(tzID) {
return 'UTC';
}
- // We expect only _ and / beside ASCII letters.
- // All inputs should conform to Area/Location from now on.
+ // TODO(jshin): Add support for Etc/GMT[+-]([1-9]|1[0-2])
+
+ // We expect only _, '-' and / beside ASCII letters.
+ // All inputs should conform to Area/Location(/Location)* from now on.
var match = %_Call(StringMatch, tzID, GetTimezoneNameCheckRE());
- if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID);
+ if (IS_NULL(match)) throw MakeRangeError(kExpectedTimezoneID, tzID);
+
+ var result = toTitleCaseTimezoneLocation(match[1]) + '/' +
+ toTitleCaseTimezoneLocation(match[2]);
- var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]);
- var i = 3;
- while (!IS_UNDEFINED(match[i]) && i < match.length) {
- result = result + '_' + toTitleCaseWord(match[i]);
- i++;
+ if (!IS_UNDEFINED(match[3]) && 3 < match.length) {
+ var locations = %_Call(StringSplit, match[3], '/');
+ // The 1st element is empty. Starts with i=1.
+ for (var i = 1; i < locations.length; i++) {
+ result = result + '/' + toTitleCaseTimezoneLocation(locations[i]);
+ }
}
return result;
« no previous file with comments | « no previous file | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698