Title: [129855] trunk/Source/WebCore
Revision
129855
Author
yo...@chromium.org
Date
2012-09-28 00:03:29 -0700 (Fri, 28 Sep 2012)

Log Message

[Forms] Adding DateTimeMonthFieldElement and DateTimeYearFieldElement
https://bugs.webkit.org/show_bug.cgi?id=97864

Reviewed by Kent Tamura.

This patch is a part of preparation of implementing multiple fields
date/time input UI.

This patch introduces DateTimeMonthFieldElement and DateTimeYearFieldElement
classes for implementing multiple fields "month" input type.

Multiple fields "month" input type uses two fields for month and year
in locale dependent order. Month field display month as two digit.
Year field display year as four digits in usual case and can display
up to 6 digits to support maximum year 275760, defined in HTML5
specification.

This patch also changes default value for step down and up on empty
field to better UI in year field. Year field displays current year
when step down and up on empty field rather than minimum year 1, or
maximum year 275760.

Note: This patch affects ports which enable both ENABLE_INPUT_TYPE_TIME
and ENABLE_INPUT_MULTIPLE_FIELDS_UI.

No new tests. This patch doesn't change behavior.

* html/shadow/DateTimeFieldElements.cpp:
(WebCore::DateTimeMonthFieldElement::DateTimeMonthFieldElement): Added.
(WebCore::DateTimeMonthFieldElement::create): Added.
(WebCore::DateTimeMonthFieldElement::populateDateTimeFieldsState): Added.
(WebCore::DateTimeMonthFieldElement::setValueAsDate): Added.
(WebCore::DateTimeMonthFieldElement::setValueAsDateTimeFieldsState): Added.
(WebCore::DateTimeYearFieldElement::DateTimeYearFieldElement): Added.
(WebCore::DateTimeYearFieldElement::create): Added.
(WebCore::DateTimeYearFieldElement::defaultValueForStepDown): Added.
(WebCore::DateTimeYearFieldElement::defaultValueForStepUp): Added.
(WebCore::DateTimeYearFieldElement::populateDateTimeFieldsState): Added.
(WebCore::DateTimeYearFieldElement::setValueAsDate): Added.
(WebCore::DateTimeYearFieldElement::setValueAsDateTimeFieldsState): Added.
* html/shadow/DateTimeFieldElements.h:
(DateTimeMonthFieldElement): Added.
(DateTimeYearFieldElement): Added.
* html/shadow/DateTimeNumericFieldElement.cpp:
(WebCore::DateTimeNumericFieldElement::Range::isInRange): Added for ease of checking value is in range.
(WebCore::DateTimeNumericFieldElement::defaultValueForStepDown): Added for default behavior.
(WebCore::DateTimeNumericFieldElement::defaultValueForStepUp): ditto.
(WebCore::DateTimeNumericFieldElement::stepDown): Changed to use defaultValueForStepDown instead of maximum field value.
(WebCore::DateTimeNumericFieldElement::stepUp):  Changed to use defaultValueForStepUp minium field value.
(WebCore::DateTimeNumericFieldElement::value): Changed to use "%04d" when maximum field value is greater than 999 for year field.
* html/shadow/DateTimeNumericFieldElement.h:
(DateTimeNumericFieldElement): Changed to add declarations of defaultValueForStepDown() and defaultValueForStepUp().

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (129854 => 129855)


--- trunk/Source/WebCore/ChangeLog	2012-09-28 06:18:15 UTC (rev 129854)
+++ trunk/Source/WebCore/ChangeLog	2012-09-28 07:03:29 UTC (rev 129855)
@@ -1,3 +1,58 @@
+2012-09-28  Yoshifumi Inoue  <yo...@chromium.org>
+
+        [Forms] Adding DateTimeMonthFieldElement and DateTimeYearFieldElement
+        https://bugs.webkit.org/show_bug.cgi?id=97864
+
+        Reviewed by Kent Tamura.
+
+        This patch is a part of preparation of implementing multiple fields
+        date/time input UI.
+
+        This patch introduces DateTimeMonthFieldElement and DateTimeYearFieldElement
+        classes for implementing multiple fields "month" input type.
+
+        Multiple fields "month" input type uses two fields for month and year
+        in locale dependent order. Month field display month as two digit.
+        Year field display year as four digits in usual case and can display
+        up to 6 digits to support maximum year 275760, defined in HTML5
+        specification.
+
+        This patch also changes default value for step down and up on empty
+        field to better UI in year field. Year field displays current year
+        when step down and up on empty field rather than minimum year 1, or
+        maximum year 275760.
+
+        Note: This patch affects ports which enable both ENABLE_INPUT_TYPE_TIME
+        and ENABLE_INPUT_MULTIPLE_FIELDS_UI.
+
+        No new tests. This patch doesn't change behavior.
+
+        * html/shadow/DateTimeFieldElements.cpp:
+        (WebCore::DateTimeMonthFieldElement::DateTimeMonthFieldElement): Added.
+        (WebCore::DateTimeMonthFieldElement::create): Added.
+        (WebCore::DateTimeMonthFieldElement::populateDateTimeFieldsState): Added.
+        (WebCore::DateTimeMonthFieldElement::setValueAsDate): Added.
+        (WebCore::DateTimeMonthFieldElement::setValueAsDateTimeFieldsState): Added.
+        (WebCore::DateTimeYearFieldElement::DateTimeYearFieldElement): Added.
+        (WebCore::DateTimeYearFieldElement::create): Added.
+        (WebCore::DateTimeYearFieldElement::defaultValueForStepDown): Added.
+        (WebCore::DateTimeYearFieldElement::defaultValueForStepUp): Added.
+        (WebCore::DateTimeYearFieldElement::populateDateTimeFieldsState): Added.
+        (WebCore::DateTimeYearFieldElement::setValueAsDate): Added.
+        (WebCore::DateTimeYearFieldElement::setValueAsDateTimeFieldsState): Added.
+        * html/shadow/DateTimeFieldElements.h:
+        (DateTimeMonthFieldElement): Added.
+        (DateTimeYearFieldElement): Added.
+        * html/shadow/DateTimeNumericFieldElement.cpp:
+        (WebCore::DateTimeNumericFieldElement::Range::isInRange): Added for ease of checking value is in range.
+        (WebCore::DateTimeNumericFieldElement::defaultValueForStepDown): Added for default behavior.
+        (WebCore::DateTimeNumericFieldElement::defaultValueForStepUp): ditto.
+        (WebCore::DateTimeNumericFieldElement::stepDown): Changed to use defaultValueForStepDown instead of maximum field value.
+        (WebCore::DateTimeNumericFieldElement::stepUp):  Changed to use defaultValueForStepUp minium field value.
+        (WebCore::DateTimeNumericFieldElement::value): Changed to use "%04d" when maximum field value is greater than 999 for year field.
+        * html/shadow/DateTimeNumericFieldElement.h:
+        (DateTimeNumericFieldElement): Changed to add declarations of defaultValueForStepDown() and defaultValueForStepUp().
+
 2012-09-27  Yoshifumi Inoue  <yo...@chromium.org>
 
         [Forms] Adding placeholder feature to DateTimeNumericElement, and update its existing subclasses.

Modified: trunk/Source/WebCore/html/shadow/DateTimeFieldElements.cpp (129854 => 129855)


--- trunk/Source/WebCore/html/shadow/DateTimeFieldElements.cpp	2012-09-28 06:18:15 UTC (rev 129854)
+++ trunk/Source/WebCore/html/shadow/DateTimeFieldElements.cpp	2012-09-28 07:03:29 UTC (rev 129855)
@@ -30,6 +30,8 @@
 #include "DateComponents.h"
 #include "DateTimeFieldsState.h"
 #include "LocalizedStrings.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/DateMath.h>
 
 namespace WebCore {
 
@@ -256,6 +258,47 @@
 
 // ----------------------------
 
+DateTimeMonthFieldElement::DateTimeMonthFieldElement(Document* document, FieldOwner& fieldOwner, const String& placeholder)
+    : DateTimeNumericFieldElement(document, fieldOwner, 1, 12, placeholder)
+{
+}
+
+PassRefPtr<DateTimeMonthFieldElement> DateTimeMonthFieldElement::create(Document* document, FieldOwner& fieldOwner, const String& placeholder)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, monthPsuedoId, ("-webkit-datetime-edit-month-field"));
+    RefPtr<DateTimeMonthFieldElement> field = adoptRef(new DateTimeMonthFieldElement(document, fieldOwner, placeholder));
+    field->initialize(monthPsuedoId, AXMonthFieldText());
+    return field.release();
+}
+
+void DateTimeMonthFieldElement::populateDateTimeFieldsState(DateTimeFieldsState& dateTimeFieldsState)
+{
+    dateTimeFieldsState.setMonth(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue);
+}
+
+void DateTimeMonthFieldElement::setValueAsDate(const DateComponents& date)
+{
+    setValueAsInteger(date.month() + 1);
+}
+
+void DateTimeMonthFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState& dateTimeFieldsState, const DateComponents& dateForReadOnlyField)
+{
+    if (!dateTimeFieldsState.hasMonth()) {
+        setEmptyValue(dateForReadOnlyField);
+        return;
+    }
+
+    const unsigned value = dateTimeFieldsState.month();
+    if (range().isInRange(static_cast<int>(value))) {
+        setValueAsInteger(value);
+        return;
+    }
+
+    setEmptyValue(dateForReadOnlyField);
+}
+
+// ----------------------------
+
 DateTimeSecondFieldElement::DateTimeSecondFieldElement(Document* document, FieldOwner& fieldOwner)
     : DateTimeNumericFieldElement(document, fieldOwner, 0, 59, "--")
 {
@@ -295,6 +338,72 @@
     setValueAsInteger(value);
 }
 
+// ----------------------------
+
+// HTML5 uses ISO-8601 format with year >= 1. Gregorian calendar started in
+// 1582. However, we need to support 0001-01-01 in Gregorian calendar rule.
+static const int minimumYear = 1;
+// Date in ECMAScript can't represent dates later than 275760-09-13T00:00Z.
+// So, we have the same upper limit in HTML5 dates.
+static const int maximumYear = 275760;
+
+DateTimeYearFieldElement::DateTimeYearFieldElement(Document* document, FieldOwner& fieldOwner, const String& placeholder)
+    : DateTimeNumericFieldElement(document, fieldOwner, minimumYear, maximumYear, placeholder)
+{
+}
+
+PassRefPtr<DateTimeYearFieldElement> DateTimeYearFieldElement::create(Document* document, FieldOwner& fieldOwner, const String& placeholder)
+{
+    DEFINE_STATIC_LOCAL(AtomicString, yearPsuedoId, ("-webkit-datetime-edit-year-field"));
+    RefPtr<DateTimeYearFieldElement> field = adoptRef(new DateTimeYearFieldElement(document, fieldOwner, placeholder));
+    field->initialize(yearPsuedoId, AXYearFieldText());
+    return field.release();
+}
+
+int DateTimeYearFieldElement::defaultValueForStepDown() const
+{
+    double current = currentTimeMS();
+    double utcOffset = calculateUTCOffset();
+    double dstOffset = calculateDSTOffset(current, utcOffset);
+    int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+    current += offset * msPerMinute;
+
+    DateComponents date;
+    date.setMillisecondsSinceEpochForMonth(current);
+    return date.fullYear();
+}
+
+int DateTimeYearFieldElement::defaultValueForStepUp() const
+{
+    return defaultValueForStepDown();
+}
+
+void DateTimeYearFieldElement::populateDateTimeFieldsState(DateTimeFieldsState& dateTimeFieldsState)
+{
+    dateTimeFieldsState.setYear(hasValue() ? valueAsInteger() : DateTimeFieldsState::emptyValue);
+}
+
+void DateTimeYearFieldElement::setValueAsDate(const DateComponents& date)
+{
+    setValueAsInteger(date.fullYear());
+}
+
+void DateTimeYearFieldElement::setValueAsDateTimeFieldsState(const DateTimeFieldsState& dateTimeFieldsState, const DateComponents& dateForReadOnlyField)
+{
+    if (!dateTimeFieldsState.hasYear()) {
+        setEmptyValue(dateForReadOnlyField);
+        return;
+    }
+
+    const unsigned value = dateTimeFieldsState.year();
+    if (range().isInRange(static_cast<int>(value))) {
+        setValueAsInteger(value);
+        return;
+    }
+
+    setEmptyValue(dateForReadOnlyField);
+}
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/html/shadow/DateTimeFieldElements.h (129854 => 129855)


--- trunk/Source/WebCore/html/shadow/DateTimeFieldElements.h	2012-09-28 06:18:15 UTC (rev 129854)
+++ trunk/Source/WebCore/html/shadow/DateTimeFieldElements.h	2012-09-28 07:03:29 UTC (rev 129855)
@@ -103,6 +103,21 @@
     virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
 };
 
+class DateTimeMonthFieldElement : public DateTimeNumericFieldElement {
+    WTF_MAKE_NONCOPYABLE(DateTimeMonthFieldElement);
+
+public:
+    static PassRefPtr<DateTimeMonthFieldElement> create(Document*, FieldOwner&, const String& placeholder);
+
+private:
+    DateTimeMonthFieldElement(Document*, FieldOwner&, const String& placeholder);
+
+    // DateTimeFieldElement functions.
+    virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
+    virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
+    virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
+};
+
 class DateTimeSecondFieldElement : public DateTimeNumericFieldElement {
     WTF_MAKE_NONCOPYABLE(DateTimeSecondFieldElement);
 
@@ -118,6 +133,25 @@
     virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
 };
 
+class DateTimeYearFieldElement : public DateTimeNumericFieldElement {
+    WTF_MAKE_NONCOPYABLE(DateTimeYearFieldElement);
+
+public:
+    static PassRefPtr<DateTimeYearFieldElement> create(Document*, FieldOwner&, const String& placeholder);
+
+private:
+    DateTimeYearFieldElement(Document*, FieldOwner&, const String& placeholder);
+
+    // DateTimeFieldElement functions.
+    virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
+    virtual void setValueAsDate(const DateComponents&) OVERRIDE FINAL;
+    virtual void setValueAsDateTimeFieldsState(const DateTimeFieldsState&, const DateComponents& dateForReadOnlyField) OVERRIDE FINAL;
+
+    // DateTimeNumericFieldElement functions.
+    virtual int defaultValueForStepDown() const OVERRIDE FINAL;
+    virtual int defaultValueForStepUp() const OVERRIDE FINAL;
+};
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp (129854 => 129855)


--- trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp	2012-09-28 06:18:15 UTC (rev 129854)
+++ trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp	2012-09-28 07:03:29 UTC (rev 129855)
@@ -47,6 +47,13 @@
     return std::min(std::max(value, minimum), maximum);
 }
 
+bool DateTimeNumericFieldElement::Range::isInRange(int value) const
+{
+    return value >= minimum && value <= maximum;
+}
+
+// ----------------------------
+
 DateTimeNumericFieldElement::DateTimeNumericFieldElement(Document* document, FieldOwner& fieldOwner, int minimum, int maximum, const String& placeholder)
     : DateTimeFieldElement(document, fieldOwner)
     , m_lastDigitCharTime(0)
@@ -57,6 +64,16 @@
 {
 }
 
+int DateTimeNumericFieldElement::defaultValueForStepDown() const
+{
+    return m_range.maximum;
+}
+
+int DateTimeNumericFieldElement::defaultValueForStepUp() const
+{
+    return m_range.minimum;
+}
+
 void DateTimeNumericFieldElement::didBlur()
 {
     m_lastDigitCharTime = 0;
@@ -138,7 +155,7 @@
     if (m_hasValue)
         setValueAsInteger(m_value == m_range.minimum ? m_range.maximum : clampValue(m_value - 1), DispatchEvent);
     else
-        setValueAsInteger(m_range.maximum, DispatchEvent);
+        setValueAsInteger(defaultValueForStepDown(), DispatchEvent);
 }
 
 void DateTimeNumericFieldElement::stepUp()
@@ -146,7 +163,7 @@
     if (m_hasValue)
         setValueAsInteger(m_value == m_range.maximum ? m_range.minimum : clampValue(m_value + 1), DispatchEvent);
     else
-        setValueAsInteger(m_range.minimum, DispatchEvent);
+        setValueAsInteger(defaultValueForStepUp(), DispatchEvent);
 }
 
 String DateTimeNumericFieldElement::value() const
@@ -156,7 +173,7 @@
 
     Localizer& localizer = this->localizer();
     if (m_range.maximum > 999)
-        return localizer.convertToLocalizedNumber(String::number(m_value));
+        return localizer.convertToLocalizedNumber(String::format("%04d", m_value));
 
     if (m_range.maximum > 99)
         return localizer.convertToLocalizedNumber(String::format("%03d", m_value));

Modified: trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h (129854 => 129855)


--- trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h	2012-09-28 06:18:15 UTC (rev 129854)
+++ trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h	2012-09-28 07:03:29 UTC (rev 129855)
@@ -45,6 +45,7 @@
     struct Range {
         Range(int minimum, int maximum);
         int clampValue(int) const;
+        bool isInRange(int) const;
 
         int maximum;
         int minimum;
@@ -53,6 +54,8 @@
     DateTimeNumericFieldElement(Document*, FieldOwner&, int minimum, int maximum, const String& placeholder);
 
     int clampValue(int value) const { return m_range.clampValue(value); }
+    virtual int defaultValueForStepDown() const;
+    virtual int defaultValueForStepUp() const;
     const Range& range() const { return m_range; }
 
     // DateTimeFieldElement functions.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to