summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/text/Localizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/text/Localizer.cpp')
-rw-r--r--Source/WebCore/platform/text/Localizer.cpp174
1 files changed, 171 insertions, 3 deletions
diff --git a/Source/WebCore/platform/text/Localizer.cpp b/Source/WebCore/platform/text/Localizer.cpp
index 8e7725736..9c712b30c 100644
--- a/Source/WebCore/platform/text/Localizer.cpp
+++ b/Source/WebCore/platform/text/Localizer.cpp
@@ -31,10 +31,134 @@
#include "config.h"
#include "Localizer.h"
+#include "DateTimeFormat.h"
#include <wtf/text/StringBuilder.h>
namespace WebCore {
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+
+class DateTimeStringBuilder : private DateTimeFormat::TokenHandler {
+ WTF_MAKE_NONCOPYABLE(DateTimeStringBuilder);
+
+public:
+ // The argument objects must be alive until this object dies.
+ DateTimeStringBuilder(Localizer&, const DateComponents&);
+
+ bool build(const String&);
+ String toString();
+
+private:
+ // DateTimeFormat::TokenHandler functions.
+ virtual void visitField(DateTimeFormat::FieldType, int) OVERRIDE FINAL;
+ virtual void visitLiteral(const String&) OVERRIDE FINAL;
+
+ String zeroPadString(const String&, size_t width);
+ void appendNumber(int number, size_t width);
+
+ StringBuilder m_builder;
+ Localizer& m_localizer;
+ const DateComponents& m_date;
+};
+
+DateTimeStringBuilder::DateTimeStringBuilder(Localizer& localizer, const DateComponents& date)
+ : m_localizer(localizer)
+ , m_date(date)
+{
+}
+
+bool DateTimeStringBuilder::build(const String& formatString)
+{
+ m_builder.reserveCapacity(formatString.length());
+ return DateTimeFormat::parse(formatString, *this);
+}
+
+String DateTimeStringBuilder::zeroPadString(const String& string, size_t width)
+{
+ if (string.length() >= width)
+ return string;
+ StringBuilder zeroPaddedStringBuilder;
+ zeroPaddedStringBuilder.reserveCapacity(width);
+ for (size_t i = string.length(); i < width; ++i)
+ zeroPaddedStringBuilder.append("0");
+ zeroPaddedStringBuilder.append(string);
+ return zeroPaddedStringBuilder.toString();
+}
+
+void DateTimeStringBuilder::appendNumber(int number, size_t width)
+{
+ String zeroPaddedNumberString = zeroPadString(String::number(number), width);
+ m_builder.append(m_localizer.convertToLocalizedNumber(zeroPaddedNumberString));
+}
+
+void DateTimeStringBuilder::visitField(DateTimeFormat::FieldType fieldType, int numberOfPatternCharacters)
+{
+ switch (fieldType) {
+ case DateTimeFormat::FieldTypeYear:
+ // Always use padding width of 4 so it matches DateTimeEditElement.
+ appendNumber(m_date.fullYear(), 4);
+ return;
+ case DateTimeFormat::FieldTypeMonth:
+ // Always use padding width of 2 so it matches DateTimeEditElement.
+ appendNumber(m_date.month() + 1, 2);
+ return;
+ case DateTimeFormat::FieldTypeDayOfMonth:
+ // Always use padding width of 2 so it matches DateTimeEditElement.
+ appendNumber(m_date.monthDay(), 2);
+ return;
+ case DateTimeFormat::FieldTypePeriod:
+ m_builder.append(m_localizer.timeAMPMLabels()[(m_date.hour() >= 12 ? 1 : 0)]);
+ return;
+ case DateTimeFormat::FieldTypeHour12: {
+ int hour12 = m_date.hour() % 12;
+ if (!hour12)
+ hour12 = 12;
+ appendNumber(hour12, numberOfPatternCharacters);
+ return;
+ }
+ case DateTimeFormat::FieldTypeHour23:
+ appendNumber(m_date.hour(), numberOfPatternCharacters);
+ return;
+ case DateTimeFormat::FieldTypeHour11:
+ appendNumber(m_date.hour() % 12, numberOfPatternCharacters);
+ return;
+ case DateTimeFormat::FieldTypeHour24: {
+ int hour24 = m_date.hour();
+ if (!hour24)
+ hour24 = 24;
+ appendNumber(hour24, numberOfPatternCharacters);
+ return;
+ }
+ case DateTimeFormat::FieldTypeMinute:
+ appendNumber(m_date.minute(), numberOfPatternCharacters);
+ return;
+ case DateTimeFormat::FieldTypeSecond:
+ if (!m_date.millisecond())
+ appendNumber(m_date.second(), numberOfPatternCharacters);
+ else {
+ double second = m_date.second() + m_date.millisecond() / 1000.0;
+ String zeroPaddedSecondString = zeroPadString(String::format("%.03f", second), numberOfPatternCharacters + 4);
+ m_builder.append(m_localizer.convertToLocalizedNumber(zeroPaddedSecondString));
+ }
+ return;
+ default:
+ return;
+ }
+}
+
+void DateTimeStringBuilder::visitLiteral(const String& text)
+{
+ ASSERT(text.length());
+ m_builder.append(text);
+}
+
+String DateTimeStringBuilder::toString()
+{
+ return m_builder.toString();
+}
+
+#endif
+
Localizer::~Localizer()
{
}
@@ -184,7 +308,7 @@ String Localizer::convertFromLocalizedNumber(const String& localized)
return builder.toString();
}
-#if ENABLE(INPUT_TYPE_TIME_MULTIPLE_FIELDS)
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
String Localizer::localizedDecimalSeparator()
{
initializeLocalizerData();
@@ -193,7 +317,7 @@ String Localizer::localizedDecimalSeparator()
String Localizer::timeFormat()
{
- if (!m_localizedTimeFormatText.isEmpty())
+ if (!m_localizedTimeFormatText.isNull())
return m_localizedTimeFormatText;
m_localizedTimeFormatText = "hh:mm:ss";
return m_localizedTimeFormatText;
@@ -201,12 +325,38 @@ String Localizer::timeFormat()
String Localizer::shortTimeFormat()
{
- if (!m_localizedShortTimeFormatText.isEmpty())
+ if (!m_localizedShortTimeFormatText.isNull())
return m_localizedShortTimeFormatText;
m_localizedTimeFormatText = "hh:mm";
return m_localizedShortTimeFormatText;
}
+String Localizer::dateTimeFormatWithSeconds()
+{
+ if (!m_dateTimeFormatWithSeconds.isNull())
+ return m_dateTimeFormatWithSeconds;
+ // FIXME: We should retrieve the separator and the order from the system.
+ StringBuilder builder;
+ builder.append(dateFormat());
+ builder.append(' ');
+ builder.append(timeFormat());
+ m_dateTimeFormatWithSeconds = builder.toString();
+ return m_dateTimeFormatWithSeconds;
+}
+
+String Localizer::dateTimeFormatWithoutSeconds()
+{
+ if (!m_dateTimeFormatWithoutSeconds.isNull())
+ return m_dateTimeFormatWithoutSeconds;
+ // FIXME: We should retrieve the separator and the order from the system.
+ StringBuilder builder;
+ builder.append(dateFormat());
+ builder.append(' ');
+ builder.append(shortTimeFormat());
+ m_dateTimeFormatWithoutSeconds = builder.toString();
+ return m_dateTimeFormatWithoutSeconds;
+}
+
const Vector<String>& Localizer::timeAMPMLabels()
{
if (!m_timeAMPMLabels.isEmpty())
@@ -218,4 +368,22 @@ const Vector<String>& Localizer::timeAMPMLabels()
}
#endif
+String Localizer::formatDateTime(const DateComponents& date, FormatType formatType)
+{
+#if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
+ if (date.type() != DateComponents::Time && date.type() != DateComponents::Date)
+ return String();
+ DateTimeStringBuilder builder(*this, date);
+ if (date.type() == DateComponents::Time)
+ builder.build(formatType == FormatTypeShort ? shortTimeFormat() : timeFormat());
+ else if (date.type() == DateComponents::Date)
+ builder.build(dateFormat());
+ return builder.toString();
+#else
+ UNUSED_PARAM(date);
+ UNUSED_PARAM(formatType);
+ return String();
+#endif
+}
+
}