diff options
Diffstat (limited to 'Source/WebCore/platform/text/Localizer.cpp')
-rw-r--r-- | Source/WebCore/platform/text/Localizer.cpp | 174 |
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 +} + } |