[Chromium-win] Use native digits in parsing/formatting dates in the textfield part...
authortkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Aug 2012 03:04:46 +0000 (03:04 +0000)
committertkent@chromium.org <tkent@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Aug 2012 03:04:46 +0000 (03:04 +0000)
https://bugs.webkit.org/show_bug.cgi?id=94281

Reviewed by Hajime Morita.

Source/WebCore:

Tests: Add some cases to Source/WebKit/chromium/tests/LocaleWinTest.cpp

* platform/text/LocaleWin.cpp:
(WebCore::LocaleWin::isLocalizedDigit): A helper for parseNumber(). This
return true if the specified character is one of native digits.
(WebCore::LocaleWin::parseNumber):
Try to parse ASCII digits, then try to parse native digtis. This
becomes a member of LocaleWin because it uses
convertFromLocalizedNumber().
(WebCore::LocaleWin::appendNumber): Apply convertToLocalizedNumber().
(WebCore::LocaleWin::appendTwoDigitsNumber): ditto.
(WebCore::LocaleWin::appendFourDigitsNumber): ditto.
* platform/text/LocaleWin.h:
(LocaleWin):
- Make some static functions member functions of LocaleWin.
- Add isLocalizedDigit().

Source/WebKit/chromium:

* tests/LocaleWinTest.cpp:
(TEST_F): Added formatting and parsing tests for Persian locale to check
native digit behavior.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@126126 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/text/LocaleWin.cpp
Source/WebCore/platform/text/LocaleWin.h
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/tests/LocaleWinTest.cpp

index 7f9f92f..99b2679 100644 (file)
@@ -1,3 +1,27 @@
+2012-08-20  Kent Tamura  <tkent@chromium.org>
+
+        [Chromium-win] Use native digits in parsing/formatting dates in the textfield part of input[type=date]
+        https://bugs.webkit.org/show_bug.cgi?id=94281
+
+        Reviewed by Hajime Morita.
+
+        Tests: Add some cases to Source/WebKit/chromium/tests/LocaleWinTest.cpp
+
+        * platform/text/LocaleWin.cpp:
+        (WebCore::LocaleWin::isLocalizedDigit): A helper for parseNumber(). This
+        return true if the specified character is one of native digits.
+        (WebCore::LocaleWin::parseNumber):
+        Try to parse ASCII digits, then try to parse native digtis. This
+        becomes a member of LocaleWin because it uses
+        convertFromLocalizedNumber().
+        (WebCore::LocaleWin::appendNumber): Apply convertToLocalizedNumber().
+        (WebCore::LocaleWin::appendTwoDigitsNumber): ditto.
+        (WebCore::LocaleWin::appendFourDigitsNumber): ditto.
+        * platform/text/LocaleWin.h:
+        (LocaleWin):
+        - Make some static functions member functions of LocaleWin.
+        - Add isLocalizedDigit().
+
 2012-08-20  Kentaro Hara  <haraken@chromium.org>
 
         Rename collectGarbageIfNecessary() to hintForCollectGarbage()
index d4eac40..67eeddb 100644 (file)
@@ -278,16 +278,32 @@ static Vector<DateFormatToken> parseDateFormat(const String format)
 
 // -------------------------------- Parsing
 
+bool LocaleWin::isLocalizedDigit(UChar ch)
+{
+    String normalizedDigit = convertFromLocalizedNumber(String(&ch, 1));
+    if (normalizedDigit.length() != 1)
+        return false;
+    return isASCIIDigit(normalizedDigit[0]);
+}
+
 // Returns -1 if parsing fails.
-static int parseNumber(const String& input, unsigned& index)
+int LocaleWin::parseNumber(const String& input, unsigned& index)
 {
     unsigned digitsStart = index;
     while (index < input.length() && isASCIIDigit(input[index]))
         index++;
+    if (digitsStart != index) {
+        bool ok = false;
+        int number = input.substring(digitsStart, index - digitsStart).toInt(&ok);
+        return ok ? number : -1;
+    }
+
+    while (index < input.length() && isLocalizedDigit(input[index]))
+        index++;
     if (digitsStart == index)
         return -1;
     bool ok = false;
-    int number = input.substring(digitsStart, index - digitsStart).toInt(&ok);
+    int number = convertFromLocalizedNumber(input.substring(digitsStart, index - digitsStart)).toInt(&ok);
     return ok ? number : -1;
 }
 
@@ -403,31 +419,42 @@ double LocaleWin::parseDate(const Vector<DateFormatToken>& tokens, int baseYear,
 
 // -------------------------------- Formatting
 
-static inline void appendNumber(int value, StringBuilder& buffer)
+inline void LocaleWin::appendNumber(int value, StringBuilder& buffer)
 {
-    buffer.append(String::number(value));
+    buffer.append(convertToLocalizedNumber(String::number(value)));
 }
 
-static void appendTwoDigitsNumber(int value, StringBuilder& buffer)
+void LocaleWin::appendTwoDigitsNumber(int value, StringBuilder& buffer)
 {
-    if (value >= 0 && value < 10)
-        buffer.append("0");
-    buffer.append(String::number(value));
+    String numberString = String::number(value);
+    if (value < 0 || value >= 10) {
+        buffer.append(convertToLocalizedNumber(numberString));
+        return;
+    }
+    StringBuilder numberBuffer;
+    numberBuffer.reserveCapacity(1 + numberString.length());
+    numberBuffer.append("0");
+    numberBuffer.append(numberString);
+    buffer.append(convertToLocalizedNumber(numberBuffer.toString()));
 }
 
-static void appendFourDigitsNumber(int value, StringBuilder& buffer)
+void LocaleWin::appendFourDigitsNumber(int value, StringBuilder& buffer)
 {
+    String numberString = String::number(value);
     if (value < 0) {
-        buffer.append(String::number(value));
+        buffer.append(convertToLocalizedNumber(numberString));
         return;
     }
+    StringBuilder numberBuffer;
+    numberBuffer.reserveCapacity(3 + numberString.length());
     if (value < 10)
-        buffer.append("000");
+        numberBuffer.append("000");
     else if (value < 100)
-        buffer.append("00");
+        numberBuffer.append("00");
     else if (value < 1000)
-        buffer.append("0");
-    buffer.append(String::number(value));
+        numberBuffer.append("0");
+    numberBuffer.append(numberString);
+    buffer.append(convertToLocalizedNumber(numberBuffer.toString()));
 }
 
 String LocaleWin::formatDate(const DateComponents& dateComponents)
index f8248aa..33666b3 100644 (file)
@@ -74,8 +74,13 @@ private:
     void ensureShortMonthLabels();
     void ensureMonthLabels();
     void ensureShortDateTokens();
+    bool isLocalizedDigit(UChar);
+    int parseNumber(const String&, unsigned& index);
     int parseNumberOrMonth(const String&, unsigned& index);
     double parseDate(const Vector<DateFormatToken>&, int baseYear, const String&);
+    void appendNumber(int, StringBuilder&);
+    void appendTwoDigitsNumber(int, StringBuilder&);
+    void appendFourDigitsNumber(int, StringBuilder&);
     String formatDate(const Vector<DateFormatToken>&, int baseYear, int year, int month, int day);
 #if ENABLE(CALENDAR_PICKER)
     void ensureWeekDayShortLabels();
index f97b39c..3d42baa 100644 (file)
@@ -1,5 +1,16 @@
 2012-08-20  Kent Tamura  <tkent@chromium.org>
 
+        [Chromium-win] Use native digits in parsing/formatting dates in the textfield part of input[type=date]
+        https://bugs.webkit.org/show_bug.cgi?id=94281
+
+        Reviewed by Hajime Morita.
+
+        * tests/LocaleWinTest.cpp:
+        (TEST_F): Added formatting and parsing tests for Persian locale to check
+        native digit behavior.
+
+2012-08-20  Kent Tamura  <tkent@chromium.org>
+
         [Chromium] Make the popup positioning code testable
         https://bugs.webkit.org/show_bug.cgi?id=94086
 
index 5f5642e..32aaa53 100644 (file)
@@ -211,7 +211,10 @@ TEST_F(LocaleWinTest, TestFormat)
 
     EXPECT_STREQ("Jan-1-0001", locale->formatDate("MMM-d-yyyy", 2012, 1, January, 1).utf8().data());
     EXPECT_STREQ("Sep-13-275760", locale->formatDate("MMM-d-yyyy", 2012, 275760, September, 13).utf8().data());
-    
+
+    OwnPtr<LocaleWin> persian = LocaleWin::create(Persian);
+    // U+06F0 U+06F1 / U+06F0 U+06F8 / U+06F0 U+06F0 U+06F0 U+06F2
+    EXPECT_STREQ("\xDB\xB0\xDB\xB1/\xDB\xB0\xDB\xB8/\xDB\xB0\xDB\xB0\xDB\xB0\xDB\xB1", persian->formatDate("dd/MM/yyyy", 2012, 1, August, 1).utf8().data());
 
     // For the following test, we'd like to confirm they don't crash and their
     // results are not important because we can assume invalid arguments are
@@ -255,6 +258,10 @@ TEST_F(LocaleWinTest, TestParse)
     EXPECT_TRUE(isnan(locale->parseDate("MMMM/d/y", 2012, "November 27 2")));
     EXPECT_TRUE(isnan(locale->parseDate("MMMM/d/y", 2012, "November 32 2")));
     EXPECT_TRUE(isnan(locale->parseDate("MMMM/d/y", 2012, "-1/-1/-1")));
+
+    OwnPtr<LocaleWin> persian = LocaleWin::create(Persian);
+    // U+06F1 U+06F6 / U+06F0 U+06F8 / 2012
+    EXPECT_EQ(msForDate(2012, August, 16), persian->parseDate("dd/MM/yyyy", 2012, String::fromUTF8("\xDB\xB1\xDB\xB6/\xDB\xB0\xDB\xB8/2012")));
 }
 
 TEST_F(LocaleWinTest, formatDate)